diff options
author | Richard Weinberger <richard@nod.at> | 2011-03-23 19:43:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-23 22:46:54 -0400 |
commit | bfdc0b497faa82a0ba2f9dddcf109231dd519fcc (patch) | |
tree | 932897262447dacb7158b81209748a295d93e20b /kernel/sysctl.c | |
parent | cb16e95fa2996743a6e80a665ed2ed0590bd38cf (diff) |
sysctl: restrict write access to dmesg_restrict
When dmesg_restrict is set to 1 CAP_SYS_ADMIN is needed to read the kernel
ring buffer. But a root user without CAP_SYS_ADMIN is able to reset
dmesg_restrict to 0.
This is an issue when e.g. LXC (Linux Containers) are used and complete
user space is running without CAP_SYS_ADMIN. A unprivileged and jailed
root user can bypass the dmesg_restrict protection.
With this patch writing to dmesg_restrict is only allowed when root has
CAP_SYS_ADMIN.
Signed-off-by: Richard Weinberger <richard@nod.at>
Acked-by: Dan Rosenberg <drosenberg@vsecurity.com>
Acked-by: Serge E. Hallyn <serge@hallyn.com>
Cc: Eric Paris <eparis@redhat.com>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: James Morris <jmorris@namei.org>
Cc: Eugene Teo <eugeneteo@kernel.org>
Cc: <stable@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.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 97ab1690f5ed..c0bb32414b17 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -170,6 +170,11 @@ static int proc_taint(struct ctl_table *table, int write, | |||
170 | void __user *buffer, size_t *lenp, loff_t *ppos); | 170 | void __user *buffer, size_t *lenp, loff_t *ppos); |
171 | #endif | 171 | #endif |
172 | 172 | ||
173 | #ifdef CONFIG_PRINTK | ||
174 | static int proc_dmesg_restrict(struct ctl_table *table, int write, | ||
175 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
176 | #endif | ||
177 | |||
173 | #ifdef CONFIG_MAGIC_SYSRQ | 178 | #ifdef CONFIG_MAGIC_SYSRQ |
174 | /* Note: sysrq code uses it's own private copy */ | 179 | /* Note: sysrq code uses it's own private copy */ |
175 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; | 180 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; |
@@ -707,7 +712,7 @@ static struct ctl_table kern_table[] = { | |||
707 | .data = &kptr_restrict, | 712 | .data = &kptr_restrict, |
708 | .maxlen = sizeof(int), | 713 | .maxlen = sizeof(int), |
709 | .mode = 0644, | 714 | .mode = 0644, |
710 | .proc_handler = proc_dointvec_minmax, | 715 | .proc_handler = proc_dmesg_restrict, |
711 | .extra1 = &zero, | 716 | .extra1 = &zero, |
712 | .extra2 = &two, | 717 | .extra2 = &two, |
713 | }, | 718 | }, |
@@ -2394,6 +2399,17 @@ static int proc_taint(struct ctl_table *table, int write, | |||
2394 | return err; | 2399 | return err; |
2395 | } | 2400 | } |
2396 | 2401 | ||
2402 | #ifdef CONFIG_PRINTK | ||
2403 | static int proc_dmesg_restrict(struct ctl_table *table, int write, | ||
2404 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2405 | { | ||
2406 | if (write && !capable(CAP_SYS_ADMIN)) | ||
2407 | return -EPERM; | ||
2408 | |||
2409 | return proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
2410 | } | ||
2411 | #endif | ||
2412 | |||
2397 | struct do_proc_dointvec_minmax_conv_param { | 2413 | struct do_proc_dointvec_minmax_conv_param { |
2398 | int *min; | 2414 | int *min; |
2399 | int *max; | 2415 | int *max; |