summaryrefslogtreecommitdiff
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-10-18 03:05:54 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 14:37:23 -0700
commitfc6cd25b738c2369d7ed3a6ef2ca248b51fcd2d4 (patch)
treebd3708eac72edf06097a8a2ed72c3a3fea0b0998 /kernel/sysctl.c
parentf429cd37a21b8efc825bdbb22db7f033564cbc98 (diff)
downloadlwn-fc6cd25b738c2369d7ed3a6ef2ca248b51fcd2d4.tar.gz
lwn-fc6cd25b738c2369d7ed3a6ef2ca248b51fcd2d4.zip
sysctl: Error on bad sysctl tables
After going through the kernels sysctl tables several times it has become clear that code review and testing is just not effective in prevent problematic sysctl tables from being used in the stable kernel. I certainly can't seem to fix the problems as fast as they are introduced. Therefore this patch adds sysctl_check_table which is called when a sysctl table is registered and checks to see if we have a problematic sysctl table. The biggest part of the code is the table of valid binary sysctl entries, but since we have frozen our set of binary sysctls this table should not need to change, and it makes it much easier to detect when someone unintentionally adds a new binary sysctl value. As best as I can determine all of the several hundred errors spewed on boot up now are legitimate. [bunk@kernel.org: kernel/sysctl_check.c must #include <linux/string.h>] Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Alexey Dobriyan <adobriyan@sw.ru> Signed-off-by: Adrian Bunk <bunk@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c7150af631b5..62e53a0de4a3 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1461,7 +1461,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
static __init int sysctl_init(void)
{
+ int err;
sysctl_set_parent(NULL, root_table);
+ err = sysctl_check_table(root_table);
return 0;
}
@@ -1546,6 +1548,10 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
tmp->used = 0;
tmp->unregistering = NULL;
sysctl_set_parent(NULL, table);
+ if (sysctl_check_table(tmp->ctl_table)) {
+ kfree(tmp);
+ return NULL;
+ }
spin_lock(&sysctl_lock);
list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
spin_unlock(&sysctl_lock);