Commit eaf06b241b091357e72b76863ba16e89610d31bd

Authored by Dan Rosenberg
Committed by Linus Torvalds
1 parent 203f40a5a0

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>

Showing 6 changed files with 44 additions and 0 deletions Side-by-side Diff

Documentation/sysctl/kernel.txt
... ... @@ -28,6 +28,7 @@
28 28 - core_uses_pid
29 29 - ctrl-alt-del
30 30 - dentry-state
  31 +- dmesg_restrict
31 32 - domainname
32 33 - hostname
33 34 - hotplug
... ... @@ -210,6 +211,19 @@
210 211 mode, the ctrl-alt-del is intercepted by the program before it
211 212 ever reaches the kernel tty layer, and it's up to the program
212 213 to decide what to do with it.
  214 +
  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.
213 227  
214 228 ==============================================================
215 229  
include/linux/kernel.h
... ... @@ -293,6 +293,7 @@
293 293 unsigned int interval_msec);
294 294  
295 295 extern int printk_delay_msec;
  296 +extern int dmesg_restrict;
296 297  
297 298 /*
298 299 * Print a one-time message (analogous to WARN_ONCE() et al):
... ... @@ -261,6 +261,12 @@
261 261 }
262 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 270 int do_syslog(int type, char __user *buf, int len, bool from_file)
265 271 {
266 272 unsigned i, j, limit, count;
... ... @@ -704,6 +704,15 @@
704 704 },
705 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 716 .procname = "ngroups_max",
708 717 .data = &ngroups_max,
709 718 .maxlen = sizeof (int),
... ... @@ -39,6 +39,18 @@
39 39  
40 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 54 config SECURITY
43 55 bool "Enable different security models"
44 56 depends on SYSFS
security/commoncap.c
... ... @@ -895,6 +895,8 @@
895 895 {
896 896 if (type != SYSLOG_ACTION_OPEN && from_file)
897 897 return 0;
  898 + if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
  899 + return -EPERM;
898 900 if ((type != SYSLOG_ACTION_READ_ALL &&
899 901 type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
900 902 return -EPERM;