diff options
author | Dan Rosenberg <drosenberg@vsecurity.com> | 2010-11-11 17:05:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-12 10:55:32 -0500 |
commit | eaf06b241b091357e72b76863ba16e89610d31bd (patch) | |
tree | 83bc8667309050b3538630707513574c14c51f37 | |
parent | 203f40a5a030ed4048cd40e3bd9ab5df6c5df589 (diff) |
Restrict unprivileged access to kernel syslog
The kernel syslog contains debugging information that is often useful
during exploitation of other vulnerabilities, such as kernel heap
addresses. Rather than futilely attempt to sanitize hundreds (or
thousands) of printk statements and simultaneously cripple useful
debugging functionality, it is far simpler to create an option that
prevents unprivileged users from reading the syslog.
This patch, loosely based on grsecurity's GRKERNSEC_DMESG, creates the
dmesg_restrict sysctl. When set to "0", the default, no restrictions are
enforced. When set to "1", only users with CAP_SYS_ADMIN can read the
kernel syslog via dmesg(8) or other mechanisms.
[akpm@linux-foundation.org: explain the config option in kernel.txt]
Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Eugene Teo <eugeneteo@kernel.org>
Acked-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/sysctl/kernel.txt | 14 | ||||
-rw-r--r-- | include/linux/kernel.h | 1 | ||||
-rw-r--r-- | kernel/printk.c | 6 | ||||
-rw-r--r-- | kernel/sysctl.c | 9 | ||||
-rw-r--r-- | security/Kconfig | 12 | ||||
-rw-r--r-- | security/commoncap.c | 2 |
6 files changed, 44 insertions, 0 deletions
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 3894eaa23486..209e1584c3dc 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -28,6 +28,7 @@ show up in /proc/sys/kernel: | |||
28 | - core_uses_pid | 28 | - core_uses_pid |
29 | - ctrl-alt-del | 29 | - ctrl-alt-del |
30 | - dentry-state | 30 | - dentry-state |
31 | - dmesg_restrict | ||
31 | - domainname | 32 | - domainname |
32 | - hostname | 33 | - hostname |
33 | - hotplug | 34 | - hotplug |
@@ -213,6 +214,19 @@ to decide what to do with it. | |||
213 | 214 | ||
214 | ============================================================== | 215 | ============================================================== |
215 | 216 | ||
217 | dmesg_restrict: | ||
218 | |||
219 | This toggle indicates whether unprivileged users are prevented from using | ||
220 | dmesg(8) to view messages from the kernel's log buffer. When | ||
221 | dmesg_restrict is set to (0) there are no restrictions. When | ||
222 | dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use | ||
223 | dmesg(8). | ||
224 | |||
225 | The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default | ||
226 | value of dmesg_restrict. | ||
227 | |||
228 | ============================================================== | ||
229 | |||
216 | domainname & hostname: | 230 | domainname & hostname: |
217 | 231 | ||
218 | These files can be used to set the NIS/YP domainname and the | 232 | These files can be used to set the NIS/YP domainname and the |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b526947bdf48..fc3da9e4da19 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -293,6 +293,7 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | |||
293 | unsigned int interval_msec); | 293 | unsigned int interval_msec); |
294 | 294 | ||
295 | extern int printk_delay_msec; | 295 | extern int printk_delay_msec; |
296 | extern int dmesg_restrict; | ||
296 | 297 | ||
297 | /* | 298 | /* |
298 | * Print a one-time message (analogous to WARN_ONCE() et al): | 299 | * Print a one-time message (analogous to WARN_ONCE() et al): |
diff --git a/kernel/printk.c b/kernel/printk.c index b2ebaee8c377..38e7d5868d60 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -261,6 +261,12 @@ static inline void boot_delay_msec(void) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | #ifdef CONFIG_SECURITY_DMESG_RESTRICT | ||
265 | int dmesg_restrict = 1; | ||
266 | #else | ||
267 | int dmesg_restrict; | ||
268 | #endif | ||
269 | |||
264 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 270 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
265 | { | 271 | { |
266 | unsigned i, j, limit, count; | 272 | unsigned i, j, limit, count; |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c33a1edb799f..b65bf634035e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -704,6 +704,15 @@ static struct ctl_table kern_table[] = { | |||
704 | }, | 704 | }, |
705 | #endif | 705 | #endif |
706 | { | 706 | { |
707 | .procname = "dmesg_restrict", | ||
708 | .data = &dmesg_restrict, | ||
709 | .maxlen = sizeof(int), | ||
710 | .mode = 0644, | ||
711 | .proc_handler = proc_dointvec_minmax, | ||
712 | .extra1 = &zero, | ||
713 | .extra2 = &one, | ||
714 | }, | ||
715 | { | ||
707 | .procname = "ngroups_max", | 716 | .procname = "ngroups_max", |
708 | .data = &ngroups_max, | 717 | .data = &ngroups_max, |
709 | .maxlen = sizeof (int), | 718 | .maxlen = sizeof (int), |
diff --git a/security/Kconfig b/security/Kconfig index bd72ae623494..e80da955e687 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -39,6 +39,18 @@ config KEYS_DEBUG_PROC_KEYS | |||
39 | 39 | ||
40 | If you are unsure as to whether this is required, answer N. | 40 | If you are unsure as to whether this is required, answer N. |
41 | 41 | ||
42 | config SECURITY_DMESG_RESTRICT | ||
43 | bool "Restrict unprivileged access to the kernel syslog" | ||
44 | default n | ||
45 | help | ||
46 | This enforces restrictions on unprivileged users reading the kernel | ||
47 | syslog via dmesg(8). | ||
48 | |||
49 | If this option is not selected, no restrictions will be enforced | ||
50 | unless the dmesg_restrict sysctl is explicitly set to (1). | ||
51 | |||
52 | If you are unsure how to answer this question, answer N. | ||
53 | |||
42 | config SECURITY | 54 | config SECURITY |
43 | bool "Enable different security models" | 55 | bool "Enable different security models" |
44 | depends on SYSFS | 56 | depends on SYSFS |
diff --git a/security/commoncap.c b/security/commoncap.c index 5e632b4857e4..04b80f9912bf 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -895,6 +895,8 @@ int cap_syslog(int type, bool from_file) | |||
895 | { | 895 | { |
896 | if (type != SYSLOG_ACTION_OPEN && from_file) | 896 | if (type != SYSLOG_ACTION_OPEN && from_file) |
897 | return 0; | 897 | return 0; |
898 | if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) | ||
899 | return -EPERM; | ||
898 | if ((type != SYSLOG_ACTION_READ_ALL && | 900 | if ((type != SYSLOG_ACTION_READ_ALL && |
899 | type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) | 901 | type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) |
900 | return -EPERM; | 902 | return -EPERM; |