diff options
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 8fe465ac008a..a23315dc4498 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -85,7 +85,7 @@ EXPORT_SYMBOL(oops_in_progress); | |||
85 | * provides serialisation for access to the entire console | 85 | * provides serialisation for access to the entire console |
86 | * driver system. | 86 | * driver system. |
87 | */ | 87 | */ |
88 | static DECLARE_MUTEX(console_sem); | 88 | static DEFINE_SEMAPHORE(console_sem); |
89 | struct console *console_drivers; | 89 | struct console *console_drivers; |
90 | EXPORT_SYMBOL_GPL(console_drivers); | 90 | EXPORT_SYMBOL_GPL(console_drivers); |
91 | 91 | ||
@@ -210,7 +210,7 @@ __setup("log_buf_len=", log_buf_len_setup); | |||
210 | 210 | ||
211 | #ifdef CONFIG_BOOT_PRINTK_DELAY | 211 | #ifdef CONFIG_BOOT_PRINTK_DELAY |
212 | 212 | ||
213 | static unsigned int boot_delay; /* msecs delay after each printk during bootup */ | 213 | static int boot_delay; /* msecs delay after each printk during bootup */ |
214 | static unsigned long long loops_per_msec; /* based on boot_delay */ | 214 | static unsigned long long loops_per_msec; /* based on boot_delay */ |
215 | 215 | ||
216 | static int __init boot_delay_setup(char *str) | 216 | static int __init boot_delay_setup(char *str) |
@@ -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; |
@@ -268,7 +274,20 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
268 | char c; | 274 | char c; |
269 | int error = 0; | 275 | int error = 0; |
270 | 276 | ||
271 | error = security_syslog(type, from_file); | 277 | /* |
278 | * If this is from /proc/kmsg we only do the capabilities checks | ||
279 | * at open time. | ||
280 | */ | ||
281 | if (type == SYSLOG_ACTION_OPEN || !from_file) { | ||
282 | if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) | ||
283 | return -EPERM; | ||
284 | if ((type != SYSLOG_ACTION_READ_ALL && | ||
285 | type != SYSLOG_ACTION_SIZE_BUFFER) && | ||
286 | !capable(CAP_SYS_ADMIN)) | ||
287 | return -EPERM; | ||
288 | } | ||
289 | |||
290 | error = security_syslog(type); | ||
272 | if (error) | 291 | if (error) |
273 | return error; | 292 | return error; |
274 | 293 | ||
@@ -556,7 +575,7 @@ static void zap_locks(void) | |||
556 | /* If a crash is occurring, make sure we can't deadlock */ | 575 | /* If a crash is occurring, make sure we can't deadlock */ |
557 | spin_lock_init(&logbuf_lock); | 576 | spin_lock_init(&logbuf_lock); |
558 | /* And make sure that we print immediately */ | 577 | /* And make sure that we print immediately */ |
559 | init_MUTEX(&console_sem); | 578 | sema_init(&console_sem, 1); |
560 | } | 579 | } |
561 | 580 | ||
562 | #if defined(CONFIG_PRINTK_TIME) | 581 | #if defined(CONFIG_PRINTK_TIME) |
@@ -647,6 +666,7 @@ static inline int can_use_console(unsigned int cpu) | |||
647 | * released but interrupts still disabled. | 666 | * released but interrupts still disabled. |
648 | */ | 667 | */ |
649 | static int acquire_console_semaphore_for_printk(unsigned int cpu) | 668 | static int acquire_console_semaphore_for_printk(unsigned int cpu) |
669 | __releases(&logbuf_lock) | ||
650 | { | 670 | { |
651 | int retval = 0; | 671 | int retval = 0; |
652 | 672 | ||
@@ -1062,13 +1082,15 @@ void printk_tick(void) | |||
1062 | 1082 | ||
1063 | int printk_needs_cpu(int cpu) | 1083 | int printk_needs_cpu(int cpu) |
1064 | { | 1084 | { |
1085 | if (unlikely(cpu_is_offline(cpu))) | ||
1086 | printk_tick(); | ||
1065 | return per_cpu(printk_pending, cpu); | 1087 | return per_cpu(printk_pending, cpu); |
1066 | } | 1088 | } |
1067 | 1089 | ||
1068 | void wake_up_klogd(void) | 1090 | void wake_up_klogd(void) |
1069 | { | 1091 | { |
1070 | if (waitqueue_active(&log_wait)) | 1092 | if (waitqueue_active(&log_wait)) |
1071 | __raw_get_cpu_var(printk_pending) = 1; | 1093 | this_cpu_write(printk_pending, 1); |
1072 | } | 1094 | } |
1073 | 1095 | ||
1074 | /** | 1096 | /** |
@@ -1511,7 +1533,7 @@ int kmsg_dump_unregister(struct kmsg_dumper *dumper) | |||
1511 | } | 1533 | } |
1512 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | 1534 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); |
1513 | 1535 | ||
1514 | static const char const *kmsg_reasons[] = { | 1536 | static const char * const kmsg_reasons[] = { |
1515 | [KMSG_DUMP_OOPS] = "oops", | 1537 | [KMSG_DUMP_OOPS] = "oops", |
1516 | [KMSG_DUMP_PANIC] = "panic", | 1538 | [KMSG_DUMP_PANIC] = "panic", |
1517 | [KMSG_DUMP_KEXEC] = "kexec", | 1539 | [KMSG_DUMP_KEXEC] = "kexec", |