diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 2 | ||||
-rw-r--r-- | kernel/audit_tree.c | 1 | ||||
-rw-r--r-- | kernel/cpu.c | 55 | ||||
-rw-r--r-- | kernel/printk.c | 91 | ||||
-rw-r--r-- | kernel/softirq.c | 13 | ||||
-rw-r--r-- | kernel/sys.c | 29 | ||||
-rw-r--r-- | kernel/trace/trace.c | 8 | ||||
-rw-r--r-- | kernel/trace/trace.h | 2 |
8 files changed, 114 insertions, 87 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 21c7fa615bd3..91e53d04b6a9 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -1056,7 +1056,7 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
1056 | static void wait_for_auditd(unsigned long sleep_time) | 1056 | static void wait_for_auditd(unsigned long sleep_time) |
1057 | { | 1057 | { |
1058 | DECLARE_WAITQUEUE(wait, current); | 1058 | DECLARE_WAITQUEUE(wait, current); |
1059 | set_current_state(TASK_INTERRUPTIBLE); | 1059 | set_current_state(TASK_UNINTERRUPTIBLE); |
1060 | add_wait_queue(&audit_backlog_wait, &wait); | 1060 | add_wait_queue(&audit_backlog_wait, &wait); |
1061 | 1061 | ||
1062 | if (audit_backlog_limit && | 1062 | if (audit_backlog_limit && |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index a291aa23fb3f..43c307dc9453 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -658,6 +658,7 @@ int audit_add_tree_rule(struct audit_krule *rule) | |||
658 | struct vfsmount *mnt; | 658 | struct vfsmount *mnt; |
659 | int err; | 659 | int err; |
660 | 660 | ||
661 | rule->tree = NULL; | ||
661 | list_for_each_entry(tree, &tree_list, list) { | 662 | list_for_each_entry(tree, &tree_list, list) { |
662 | if (!strcmp(seed->pathname, tree->pathname)) { | 663 | if (!strcmp(seed->pathname, tree->pathname)) { |
663 | put_tree(seed); | 664 | put_tree(seed); |
diff --git a/kernel/cpu.c b/kernel/cpu.c index b5e4ab2d427e..198a38883e64 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -133,6 +133,27 @@ static void cpu_hotplug_done(void) | |||
133 | mutex_unlock(&cpu_hotplug.lock); | 133 | mutex_unlock(&cpu_hotplug.lock); |
134 | } | 134 | } |
135 | 135 | ||
136 | /* | ||
137 | * Wait for currently running CPU hotplug operations to complete (if any) and | ||
138 | * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects | ||
139 | * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the | ||
140 | * hotplug path before performing hotplug operations. So acquiring that lock | ||
141 | * guarantees mutual exclusion from any currently running hotplug operations. | ||
142 | */ | ||
143 | void cpu_hotplug_disable(void) | ||
144 | { | ||
145 | cpu_maps_update_begin(); | ||
146 | cpu_hotplug_disabled = 1; | ||
147 | cpu_maps_update_done(); | ||
148 | } | ||
149 | |||
150 | void cpu_hotplug_enable(void) | ||
151 | { | ||
152 | cpu_maps_update_begin(); | ||
153 | cpu_hotplug_disabled = 0; | ||
154 | cpu_maps_update_done(); | ||
155 | } | ||
156 | |||
136 | #else /* #if CONFIG_HOTPLUG_CPU */ | 157 | #else /* #if CONFIG_HOTPLUG_CPU */ |
137 | static void cpu_hotplug_begin(void) {} | 158 | static void cpu_hotplug_begin(void) {} |
138 | static void cpu_hotplug_done(void) {} | 159 | static void cpu_hotplug_done(void) {} |
@@ -541,36 +562,6 @@ static int __init alloc_frozen_cpus(void) | |||
541 | core_initcall(alloc_frozen_cpus); | 562 | core_initcall(alloc_frozen_cpus); |
542 | 563 | ||
543 | /* | 564 | /* |
544 | * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU | ||
545 | * hotplug when tasks are about to be frozen. Also, don't allow the freezer | ||
546 | * to continue until any currently running CPU hotplug operation gets | ||
547 | * completed. | ||
548 | * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the | ||
549 | * 'cpu_add_remove_lock'. And this same lock is also taken by the regular | ||
550 | * CPU hotplug path and released only after it is complete. Thus, we | ||
551 | * (and hence the freezer) will block here until any currently running CPU | ||
552 | * hotplug operation gets completed. | ||
553 | */ | ||
554 | void cpu_hotplug_disable_before_freeze(void) | ||
555 | { | ||
556 | cpu_maps_update_begin(); | ||
557 | cpu_hotplug_disabled = 1; | ||
558 | cpu_maps_update_done(); | ||
559 | } | ||
560 | |||
561 | |||
562 | /* | ||
563 | * When tasks have been thawed, re-enable regular CPU hotplug (which had been | ||
564 | * disabled while beginning to freeze tasks). | ||
565 | */ | ||
566 | void cpu_hotplug_enable_after_thaw(void) | ||
567 | { | ||
568 | cpu_maps_update_begin(); | ||
569 | cpu_hotplug_disabled = 0; | ||
570 | cpu_maps_update_done(); | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * When callbacks for CPU hotplug notifications are being executed, we must | 565 | * When callbacks for CPU hotplug notifications are being executed, we must |
575 | * ensure that the state of the system with respect to the tasks being frozen | 566 | * ensure that the state of the system with respect to the tasks being frozen |
576 | * or not, as reported by the notification, remains unchanged *throughout the | 567 | * or not, as reported by the notification, remains unchanged *throughout the |
@@ -589,12 +580,12 @@ cpu_hotplug_pm_callback(struct notifier_block *nb, | |||
589 | 580 | ||
590 | case PM_SUSPEND_PREPARE: | 581 | case PM_SUSPEND_PREPARE: |
591 | case PM_HIBERNATION_PREPARE: | 582 | case PM_HIBERNATION_PREPARE: |
592 | cpu_hotplug_disable_before_freeze(); | 583 | cpu_hotplug_disable(); |
593 | break; | 584 | break; |
594 | 585 | ||
595 | case PM_POST_SUSPEND: | 586 | case PM_POST_SUSPEND: |
596 | case PM_POST_HIBERNATION: | 587 | case PM_POST_HIBERNATION: |
597 | cpu_hotplug_enable_after_thaw(); | 588 | cpu_hotplug_enable(); |
598 | break; | 589 | break; |
599 | 590 | ||
600 | default: | 591 | default: |
diff --git a/kernel/printk.c b/kernel/printk.c index fa36e1494420..8212c1aef125 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -363,6 +363,53 @@ static void log_store(int facility, int level, | |||
363 | log_next_seq++; | 363 | log_next_seq++; |
364 | } | 364 | } |
365 | 365 | ||
366 | #ifdef CONFIG_SECURITY_DMESG_RESTRICT | ||
367 | int dmesg_restrict = 1; | ||
368 | #else | ||
369 | int dmesg_restrict; | ||
370 | #endif | ||
371 | |||
372 | static int syslog_action_restricted(int type) | ||
373 | { | ||
374 | if (dmesg_restrict) | ||
375 | return 1; | ||
376 | /* | ||
377 | * Unless restricted, we allow "read all" and "get buffer size" | ||
378 | * for everybody. | ||
379 | */ | ||
380 | return type != SYSLOG_ACTION_READ_ALL && | ||
381 | type != SYSLOG_ACTION_SIZE_BUFFER; | ||
382 | } | ||
383 | |||
384 | static int check_syslog_permissions(int type, bool from_file) | ||
385 | { | ||
386 | /* | ||
387 | * If this is from /proc/kmsg and we've already opened it, then we've | ||
388 | * already done the capabilities checks at open time. | ||
389 | */ | ||
390 | if (from_file && type != SYSLOG_ACTION_OPEN) | ||
391 | return 0; | ||
392 | |||
393 | if (syslog_action_restricted(type)) { | ||
394 | if (capable(CAP_SYSLOG)) | ||
395 | return 0; | ||
396 | /* | ||
397 | * For historical reasons, accept CAP_SYS_ADMIN too, with | ||
398 | * a warning. | ||
399 | */ | ||
400 | if (capable(CAP_SYS_ADMIN)) { | ||
401 | pr_warn_once("%s (%d): Attempt to access syslog with " | ||
402 | "CAP_SYS_ADMIN but no CAP_SYSLOG " | ||
403 | "(deprecated).\n", | ||
404 | current->comm, task_pid_nr(current)); | ||
405 | return 0; | ||
406 | } | ||
407 | return -EPERM; | ||
408 | } | ||
409 | return security_syslog(type); | ||
410 | } | ||
411 | |||
412 | |||
366 | /* /dev/kmsg - userspace message inject/listen interface */ | 413 | /* /dev/kmsg - userspace message inject/listen interface */ |
367 | struct devkmsg_user { | 414 | struct devkmsg_user { |
368 | u64 seq; | 415 | u64 seq; |
@@ -620,7 +667,8 @@ static int devkmsg_open(struct inode *inode, struct file *file) | |||
620 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 667 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
621 | return 0; | 668 | return 0; |
622 | 669 | ||
623 | err = security_syslog(SYSLOG_ACTION_READ_ALL); | 670 | err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL, |
671 | SYSLOG_FROM_READER); | ||
624 | if (err) | 672 | if (err) |
625 | return err; | 673 | return err; |
626 | 674 | ||
@@ -813,45 +861,6 @@ static inline void boot_delay_msec(int level) | |||
813 | } | 861 | } |
814 | #endif | 862 | #endif |
815 | 863 | ||
816 | #ifdef CONFIG_SECURITY_DMESG_RESTRICT | ||
817 | int dmesg_restrict = 1; | ||
818 | #else | ||
819 | int dmesg_restrict; | ||
820 | #endif | ||
821 | |||
822 | static int syslog_action_restricted(int type) | ||
823 | { | ||
824 | if (dmesg_restrict) | ||
825 | return 1; | ||
826 | /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ | ||
827 | return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; | ||
828 | } | ||
829 | |||
830 | static int check_syslog_permissions(int type, bool from_file) | ||
831 | { | ||
832 | /* | ||
833 | * If this is from /proc/kmsg and we've already opened it, then we've | ||
834 | * already done the capabilities checks at open time. | ||
835 | */ | ||
836 | if (from_file && type != SYSLOG_ACTION_OPEN) | ||
837 | return 0; | ||
838 | |||
839 | if (syslog_action_restricted(type)) { | ||
840 | if (capable(CAP_SYSLOG)) | ||
841 | return 0; | ||
842 | /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ | ||
843 | if (capable(CAP_SYS_ADMIN)) { | ||
844 | printk_once(KERN_WARNING "%s (%d): " | ||
845 | "Attempt to access syslog with CAP_SYS_ADMIN " | ||
846 | "but no CAP_SYSLOG (deprecated).\n", | ||
847 | current->comm, task_pid_nr(current)); | ||
848 | return 0; | ||
849 | } | ||
850 | return -EPERM; | ||
851 | } | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | #if defined(CONFIG_PRINTK_TIME) | 864 | #if defined(CONFIG_PRINTK_TIME) |
856 | static bool printk_time = 1; | 865 | static bool printk_time = 1; |
857 | #else | 866 | #else |
@@ -1249,7 +1258,7 @@ out: | |||
1249 | 1258 | ||
1250 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | 1259 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
1251 | { | 1260 | { |
1252 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); | 1261 | return do_syslog(type, buf, len, SYSLOG_FROM_READER); |
1253 | } | 1262 | } |
1254 | 1263 | ||
1255 | /* | 1264 | /* |
diff --git a/kernel/softirq.c b/kernel/softirq.c index b5197dcb0dad..3d6833f125d3 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip) | |||
195 | EXPORT_SYMBOL(local_bh_enable_ip); | 195 | EXPORT_SYMBOL(local_bh_enable_ip); |
196 | 196 | ||
197 | /* | 197 | /* |
198 | * We restart softirq processing for at most 2 ms, | 198 | * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times, |
199 | * and if need_resched() is not set. | 199 | * but break the loop if need_resched() is set or after 2 ms. |
200 | * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in | ||
201 | * certain cases, such as stop_machine(), jiffies may cease to | ||
202 | * increment and so we need the MAX_SOFTIRQ_RESTART limit as | ||
203 | * well to make sure we eventually return from this method. | ||
200 | * | 204 | * |
201 | * These limits have been established via experimentation. | 205 | * These limits have been established via experimentation. |
202 | * The two things to balance is latency against fairness - | 206 | * The two things to balance is latency against fairness - |
@@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip); | |||
204 | * should not be able to lock up the box. | 208 | * should not be able to lock up the box. |
205 | */ | 209 | */ |
206 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) | 210 | #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) |
211 | #define MAX_SOFTIRQ_RESTART 10 | ||
207 | 212 | ||
208 | asmlinkage void __do_softirq(void) | 213 | asmlinkage void __do_softirq(void) |
209 | { | 214 | { |
@@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void) | |||
212 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; | 217 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; |
213 | int cpu; | 218 | int cpu; |
214 | unsigned long old_flags = current->flags; | 219 | unsigned long old_flags = current->flags; |
220 | int max_restart = MAX_SOFTIRQ_RESTART; | ||
215 | 221 | ||
216 | /* | 222 | /* |
217 | * Mask out PF_MEMALLOC s current task context is borrowed for the | 223 | * Mask out PF_MEMALLOC s current task context is borrowed for the |
@@ -265,7 +271,8 @@ restart: | |||
265 | 271 | ||
266 | pending = local_softirq_pending(); | 272 | pending = local_softirq_pending(); |
267 | if (pending) { | 273 | if (pending) { |
268 | if (time_before(jiffies, end) && !need_resched()) | 274 | if (time_before(jiffies, end) && !need_resched() && |
275 | --max_restart) | ||
269 | goto restart; | 276 | goto restart; |
270 | 277 | ||
271 | wakeup_softirqd(); | 278 | wakeup_softirqd(); |
diff --git a/kernel/sys.c b/kernel/sys.c index b95d3c72ba21..2bbd9a73b54c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -362,6 +362,29 @@ int unregister_reboot_notifier(struct notifier_block *nb) | |||
362 | } | 362 | } |
363 | EXPORT_SYMBOL(unregister_reboot_notifier); | 363 | EXPORT_SYMBOL(unregister_reboot_notifier); |
364 | 364 | ||
365 | /* Add backwards compatibility for stable trees. */ | ||
366 | #ifndef PF_NO_SETAFFINITY | ||
367 | #define PF_NO_SETAFFINITY PF_THREAD_BOUND | ||
368 | #endif | ||
369 | |||
370 | static void migrate_to_reboot_cpu(void) | ||
371 | { | ||
372 | /* The boot cpu is always logical cpu 0 */ | ||
373 | int cpu = 0; | ||
374 | |||
375 | cpu_hotplug_disable(); | ||
376 | |||
377 | /* Make certain the cpu I'm about to reboot on is online */ | ||
378 | if (!cpu_online(cpu)) | ||
379 | cpu = cpumask_first(cpu_online_mask); | ||
380 | |||
381 | /* Prevent races with other tasks migrating this task */ | ||
382 | current->flags |= PF_NO_SETAFFINITY; | ||
383 | |||
384 | /* Make certain I only run on the appropriate processor */ | ||
385 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); | ||
386 | } | ||
387 | |||
365 | /** | 388 | /** |
366 | * kernel_restart - reboot the system | 389 | * kernel_restart - reboot the system |
367 | * @cmd: pointer to buffer containing command to execute for restart | 390 | * @cmd: pointer to buffer containing command to execute for restart |
@@ -373,7 +396,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); | |||
373 | void kernel_restart(char *cmd) | 396 | void kernel_restart(char *cmd) |
374 | { | 397 | { |
375 | kernel_restart_prepare(cmd); | 398 | kernel_restart_prepare(cmd); |
376 | disable_nonboot_cpus(); | 399 | migrate_to_reboot_cpu(); |
377 | syscore_shutdown(); | 400 | syscore_shutdown(); |
378 | if (!cmd) | 401 | if (!cmd) |
379 | printk(KERN_EMERG "Restarting system.\n"); | 402 | printk(KERN_EMERG "Restarting system.\n"); |
@@ -400,7 +423,7 @@ static void kernel_shutdown_prepare(enum system_states state) | |||
400 | void kernel_halt(void) | 423 | void kernel_halt(void) |
401 | { | 424 | { |
402 | kernel_shutdown_prepare(SYSTEM_HALT); | 425 | kernel_shutdown_prepare(SYSTEM_HALT); |
403 | disable_nonboot_cpus(); | 426 | migrate_to_reboot_cpu(); |
404 | syscore_shutdown(); | 427 | syscore_shutdown(); |
405 | printk(KERN_EMERG "System halted.\n"); | 428 | printk(KERN_EMERG "System halted.\n"); |
406 | kmsg_dump(KMSG_DUMP_HALT); | 429 | kmsg_dump(KMSG_DUMP_HALT); |
@@ -419,7 +442,7 @@ void kernel_power_off(void) | |||
419 | kernel_shutdown_prepare(SYSTEM_POWER_OFF); | 442 | kernel_shutdown_prepare(SYSTEM_POWER_OFF); |
420 | if (pm_power_off_prepare) | 443 | if (pm_power_off_prepare) |
421 | pm_power_off_prepare(); | 444 | pm_power_off_prepare(); |
422 | disable_nonboot_cpus(); | 445 | migrate_to_reboot_cpu(); |
423 | syscore_shutdown(); | 446 | syscore_shutdown(); |
424 | printk(KERN_EMERG "Power down.\n"); | 447 | printk(KERN_EMERG "Power down.\n"); |
425 | kmsg_dump(KMSG_DUMP_POWEROFF); | 448 | kmsg_dump(KMSG_DUMP_POWEROFF); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1a41023a1f88..e71a8be4a6ee 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -652,8 +652,6 @@ static struct { | |||
652 | ARCH_TRACE_CLOCKS | 652 | ARCH_TRACE_CLOCKS |
653 | }; | 653 | }; |
654 | 654 | ||
655 | int trace_clock_id; | ||
656 | |||
657 | /* | 655 | /* |
658 | * trace_parser_get_init - gets the buffer for trace parser | 656 | * trace_parser_get_init - gets the buffer for trace parser |
659 | */ | 657 | */ |
@@ -2826,7 +2824,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) | |||
2826 | iter->iter_flags |= TRACE_FILE_ANNOTATE; | 2824 | iter->iter_flags |= TRACE_FILE_ANNOTATE; |
2827 | 2825 | ||
2828 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | 2826 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ |
2829 | if (trace_clocks[trace_clock_id].in_ns) | 2827 | if (trace_clocks[tr->clock_id].in_ns) |
2830 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | 2828 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; |
2831 | 2829 | ||
2832 | /* stop the trace while dumping if we are not opening "snapshot" */ | 2830 | /* stop the trace while dumping if we are not opening "snapshot" */ |
@@ -3825,7 +3823,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
3825 | iter->iter_flags |= TRACE_FILE_LAT_FMT; | 3823 | iter->iter_flags |= TRACE_FILE_LAT_FMT; |
3826 | 3824 | ||
3827 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | 3825 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ |
3828 | if (trace_clocks[trace_clock_id].in_ns) | 3826 | if (trace_clocks[tr->clock_id].in_ns) |
3829 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | 3827 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; |
3830 | 3828 | ||
3831 | iter->cpu_file = tc->cpu; | 3829 | iter->cpu_file = tc->cpu; |
@@ -5095,7 +5093,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf, | |||
5095 | cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu); | 5093 | cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu); |
5096 | trace_seq_printf(s, "bytes: %ld\n", cnt); | 5094 | trace_seq_printf(s, "bytes: %ld\n", cnt); |
5097 | 5095 | ||
5098 | if (trace_clocks[trace_clock_id].in_ns) { | 5096 | if (trace_clocks[tr->clock_id].in_ns) { |
5099 | /* local or global for trace_clock */ | 5097 | /* local or global for trace_clock */ |
5100 | t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); | 5098 | t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); |
5101 | usec_rem = do_div(t, USEC_PER_SEC); | 5099 | usec_rem = do_div(t, USEC_PER_SEC); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 711ca7d3e7f1..20572ed88c5c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -700,8 +700,6 @@ enum print_line_t print_trace_line(struct trace_iterator *iter); | |||
700 | 700 | ||
701 | extern unsigned long trace_flags; | 701 | extern unsigned long trace_flags; |
702 | 702 | ||
703 | extern int trace_clock_id; | ||
704 | |||
705 | /* Standard output formatting function used for function return traces */ | 703 | /* Standard output formatting function used for function return traces */ |
706 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 704 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
707 | 705 | ||