Commit fc6cd25b authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

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: default avatarEric W. Biederman <ebiederm@xmission.com>
Cc: Alexey Dobriyan <adobriyan@sw.ru>
Signed-off-by: default avatarAdrian Bunk <bunk@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f429cd37
...@@ -1068,6 +1068,7 @@ struct ctl_table_header ...@@ -1068,6 +1068,7 @@ struct ctl_table_header
struct ctl_table_header *register_sysctl_table(struct ctl_table * table); struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
void unregister_sysctl_table(struct ctl_table_header * table); void unregister_sysctl_table(struct ctl_table_header * table);
int sysctl_check_table(struct ctl_table *table);
#else /* __KERNEL__ */ #else /* __KERNEL__ */
......
...@@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ ...@@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
rcupdate.o extable.o params.o posix-timers.o \ rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \ hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \
utsname.o utsname.o sysctl_check.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/ obj-y += time/
......
...@@ -1461,7 +1461,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) ...@@ -1461,7 +1461,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
static __init int sysctl_init(void) static __init int sysctl_init(void)
{ {
int err;
sysctl_set_parent(NULL, root_table); sysctl_set_parent(NULL, root_table);
err = sysctl_check_table(root_table);
return 0; return 0;
} }
...@@ -1546,6 +1548,10 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table) ...@@ -1546,6 +1548,10 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
tmp->used = 0; tmp->used = 0;
tmp->unregistering = NULL; tmp->unregistering = NULL;
sysctl_set_parent(NULL, table); sysctl_set_parent(NULL, table);
if (sysctl_check_table(tmp->ctl_table)) {
kfree(tmp);
return NULL;
}
spin_lock(&sysctl_lock); spin_lock(&sysctl_lock);
list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
spin_unlock(&sysctl_lock); spin_unlock(&sysctl_lock);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment