diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2009-11-12 04:39:06 -0500 |
|---|---|---|
| committer | Eric W. Biederman <ebiederm@xmission.com> | 2009-11-12 04:42:31 -0500 |
| commit | 757010f026ab3044c594003e216d00a33ed95c56 (patch) | |
| tree | 4e9d44c52c34c09b5a347688af20840be7a1c61a | |
| parent | 63395b65972c07edce595c9cc8a983016738cdac (diff) | |
sysctl binary: Reorder the tests to process wild card entries first.
A malicious user could have passed in a ctl_name of 0 and triggered
the well know ctl_name to procname mapping code, instead of the wild
card matching code. This is a slight problem as wild card entries don't
have procnames, and because in some alternate universe a network device
might have ifindex 0. So test for and handle wild card entries first.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
| -rw-r--r-- | kernel/sysctl_binary.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 0cf60400542d..b75dbf40f573 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
| @@ -1269,17 +1269,12 @@ repeat: | |||
| 1269 | for ( ; table->convert; table++) { | 1269 | for ( ; table->convert; table++) { |
| 1270 | int len = 0; | 1270 | int len = 0; |
| 1271 | 1271 | ||
| 1272 | /* Use the well known sysctl number to proc name mapping */ | ||
| 1273 | if (ctl_name == table->ctl_name) { | ||
| 1274 | len = strlen(table->procname); | ||
| 1275 | memcpy(path, table->procname, len); | ||
| 1276 | } | ||
| 1277 | #ifdef CONFIG_NET | ||
| 1278 | /* | 1272 | /* |
| 1279 | * For a wild card entry map from ifindex to network | 1273 | * For a wild card entry map from ifindex to network |
| 1280 | * device name. | 1274 | * device name. |
| 1281 | */ | 1275 | */ |
| 1282 | else if (!table->ctl_name) { | 1276 | if (!table->ctl_name) { |
| 1277 | #ifdef CONFIG_NET | ||
| 1283 | struct net *net = current->nsproxy->net_ns; | 1278 | struct net *net = current->nsproxy->net_ns; |
| 1284 | struct net_device *dev; | 1279 | struct net_device *dev; |
| 1285 | dev = dev_get_by_index(net, ctl_name); | 1280 | dev = dev_get_by_index(net, ctl_name); |
| @@ -1288,8 +1283,12 @@ repeat: | |||
| 1288 | memcpy(path, dev->name, len); | 1283 | memcpy(path, dev->name, len); |
| 1289 | dev_put(dev); | 1284 | dev_put(dev); |
| 1290 | } | 1285 | } |
| 1291 | } | ||
| 1292 | #endif | 1286 | #endif |
| 1287 | /* Use the well known sysctl number to proc name mapping */ | ||
| 1288 | } else if (ctl_name == table->ctl_name) { | ||
| 1289 | len = strlen(table->procname); | ||
| 1290 | memcpy(path, table->procname, len); | ||
| 1291 | } | ||
| 1293 | if (len) { | 1292 | if (len) { |
| 1294 | path += len; | 1293 | path += len; |
| 1295 | if (table->child) { | 1294 | if (table->child) { |
