]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/printk.c
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
[karo-tx-linux.git] / kernel / printk.c
index 5417784a76b5afa218196634954ba962273de0a9..4642a5c439eb324b8d3e79872e589439c705cd20 100644 (file)
@@ -255,6 +255,12 @@ static inline void boot_delay_msec(void)
 }
 #endif
 
+#ifdef CONFIG_SECURITY_DMESG_RESTRICT
+int dmesg_restrict = 1;
+#else
+int dmesg_restrict;
+#endif
+
 int do_syslog(int type, char __user *buf, int len, bool from_file)
 {
        unsigned i, j, limit, count;
@@ -262,7 +268,20 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
        char c;
        int error = 0;
 
-       error = security_syslog(type, from_file);
+       /*
+        * If this is from /proc/kmsg we only do the capabilities checks
+        * at open time.
+        */
+       if (type == SYSLOG_ACTION_OPEN || !from_file) {
+               if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               if ((type != SYSLOG_ACTION_READ_ALL &&
+                    type != SYSLOG_ACTION_SIZE_BUFFER) &&
+                   !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+       }
+
+       error = security_syslog(type);
        if (error)
                return error;
 
@@ -1049,21 +1068,23 @@ static DEFINE_PER_CPU(int, printk_pending);
 
 void printk_tick(void)
 {
-       if (__get_cpu_var(printk_pending)) {
-               __get_cpu_var(printk_pending) = 0;
+       if (__this_cpu_read(printk_pending)) {
+               __this_cpu_write(printk_pending, 0);
                wake_up_interruptible(&log_wait);
        }
 }
 
 int printk_needs_cpu(int cpu)
 {
-       return per_cpu(printk_pending, cpu);
+       if (cpu_is_offline(cpu))
+               printk_tick();
+       return __this_cpu_read(printk_pending);
 }
 
 void wake_up_klogd(void)
 {
        if (waitqueue_active(&log_wait))
-               __raw_get_cpu_var(printk_pending) = 1;
+               this_cpu_write(printk_pending, 1);
 }
 
 /**