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 | |
| 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')
| -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; |
