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.
Showing the changes to kernel/sysctl_binary.c (1 of 1 file). Show all
Unified · Split
| @@ -1269,17 +1269,12 @@ repeat: · 1268 unmodified lines | ||
| 1269 | 1269 | for ( ; table->convert; table++) { |
| 1270 | 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 | 1273 | * For a wild card entry map from ifindex to network |
| 1280 | 1274 | * device name. |
| 1281 | 1275 | */ |
| 1282 | − else if (!table->ctl_name) { | |
| 1276 | + if (!table->ctl_name) { | |
| 1277 | +#ifdef CONFIG_NET | |
| 1283 | 1278 | struct net *net = current->nsproxy->net_ns; |
| 1284 | 1279 | struct net_device *dev; |
| 1285 | 1280 | dev = dev_get_by_index(net, ctl_name); |
| @@ -1288,8 +1283,12 @@ repeat: · 2 unmodified lines | ||
| 1288 | 1283 | memcpy(path, dev->name, len); |
| 1289 | 1284 | dev_put(dev); |
| 1290 | 1285 | } |
| 1291 | − } | |
| 1292 | 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 | 1292 | if (len) { |
| 1294 | 1293 | path += len; |
| 1295 | 1294 | if (table->child) { |