diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bounds.c | 23 | ||||
-rw-r--r-- | kernel/cpuset.c | 22 | ||||
-rw-r--r-- | kernel/exit.c | 2 | ||||
-rw-r--r-- | kernel/fork.c | 6 | ||||
-rw-r--r-- | kernel/hrtimer.c | 15 | ||||
-rw-r--r-- | kernel/kexec.c | 3 | ||||
-rw-r--r-- | kernel/kprobes.c | 349 | ||||
-rw-r--r-- | kernel/power/console.c | 27 | ||||
-rw-r--r-- | kernel/sys.c | 27 |
9 files changed, 361 insertions, 113 deletions
diff --git a/kernel/bounds.c b/kernel/bounds.c new file mode 100644 index 000000000000..c3c55544db2f --- /dev/null +++ b/kernel/bounds.c | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Generate definitions needed by the preprocessor. | ||
3 | * This code generates raw asm output which is post-processed | ||
4 | * to extract and format the required data. | ||
5 | */ | ||
6 | |||
7 | #define __GENERATING_BOUNDS_H | ||
8 | /* Include headers that define the enum constants of interest */ | ||
9 | #include <linux/page-flags.h> | ||
10 | #include <linux/mmzone.h> | ||
11 | |||
12 | #define DEFINE(sym, val) \ | ||
13 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
14 | |||
15 | #define BLANK() asm volatile("\n->" : : ) | ||
16 | |||
17 | void foo(void) | ||
18 | { | ||
19 | /* The enum constants to put into include/linux/bounds.h */ | ||
20 | DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS); | ||
21 | DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES); | ||
22 | /* End of constants */ | ||
23 | } | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 8b35fbd8292f..024888bb9814 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -941,7 +941,7 @@ static int update_nodemask(struct cpuset *cs, char *buf) | |||
941 | cs->mems_generation = cpuset_mems_generation++; | 941 | cs->mems_generation = cpuset_mems_generation++; |
942 | mutex_unlock(&callback_mutex); | 942 | mutex_unlock(&callback_mutex); |
943 | 943 | ||
944 | cpuset_being_rebound = cs; /* causes mpol_copy() rebind */ | 944 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ |
945 | 945 | ||
946 | fudge = 10; /* spare mmarray[] slots */ | 946 | fudge = 10; /* spare mmarray[] slots */ |
947 | fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */ | 947 | fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */ |
@@ -992,7 +992,7 @@ static int update_nodemask(struct cpuset *cs, char *buf) | |||
992 | * rebind the vma mempolicies of each mm in mmarray[] to their | 992 | * rebind the vma mempolicies of each mm in mmarray[] to their |
993 | * new cpuset, and release that mm. The mpol_rebind_mm() | 993 | * new cpuset, and release that mm. The mpol_rebind_mm() |
994 | * call takes mmap_sem, which we couldn't take while holding | 994 | * call takes mmap_sem, which we couldn't take while holding |
995 | * tasklist_lock. Forks can happen again now - the mpol_copy() | 995 | * tasklist_lock. Forks can happen again now - the mpol_dup() |
996 | * cpuset_being_rebound check will catch such forks, and rebind | 996 | * cpuset_being_rebound check will catch such forks, and rebind |
997 | * their vma mempolicies too. Because we still hold the global | 997 | * their vma mempolicies too. Because we still hold the global |
998 | * cgroup_mutex, we know that no other rebind effort will | 998 | * cgroup_mutex, we know that no other rebind effort will |
@@ -1958,22 +1958,14 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk) | |||
1958 | } | 1958 | } |
1959 | 1959 | ||
1960 | /** | 1960 | /** |
1961 | * cpuset_zonelist_valid_mems_allowed - check zonelist vs. curremt mems_allowed | 1961 | * cpuset_nodemask_valid_mems_allowed - check nodemask vs. curremt mems_allowed |
1962 | * @zl: the zonelist to be checked | 1962 | * @nodemask: the nodemask to be checked |
1963 | * | 1963 | * |
1964 | * Are any of the nodes on zonelist zl allowed in current->mems_allowed? | 1964 | * Are any of the nodes in the nodemask allowed in current->mems_allowed? |
1965 | */ | 1965 | */ |
1966 | int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl) | 1966 | int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) |
1967 | { | 1967 | { |
1968 | int i; | 1968 | return nodes_intersects(*nodemask, current->mems_allowed); |
1969 | |||
1970 | for (i = 0; zl->zones[i]; i++) { | ||
1971 | int nid = zone_to_nid(zl->zones[i]); | ||
1972 | |||
1973 | if (node_isset(nid, current->mems_allowed)) | ||
1974 | return 1; | ||
1975 | } | ||
1976 | return 0; | ||
1977 | } | 1969 | } |
1978 | 1970 | ||
1979 | /* | 1971 | /* |
diff --git a/kernel/exit.c b/kernel/exit.c index 97f609f574b1..2a9d98c641ac 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -967,7 +967,7 @@ NORET_TYPE void do_exit(long code) | |||
967 | proc_exit_connector(tsk); | 967 | proc_exit_connector(tsk); |
968 | exit_notify(tsk, group_dead); | 968 | exit_notify(tsk, group_dead); |
969 | #ifdef CONFIG_NUMA | 969 | #ifdef CONFIG_NUMA |
970 | mpol_free(tsk->mempolicy); | 970 | mpol_put(tsk->mempolicy); |
971 | tsk->mempolicy = NULL; | 971 | tsk->mempolicy = NULL; |
972 | #endif | 972 | #endif |
973 | #ifdef CONFIG_FUTEX | 973 | #ifdef CONFIG_FUTEX |
diff --git a/kernel/fork.c b/kernel/fork.c index c674aa8d3c31..6067e429f281 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -279,7 +279,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
279 | if (!tmp) | 279 | if (!tmp) |
280 | goto fail_nomem; | 280 | goto fail_nomem; |
281 | *tmp = *mpnt; | 281 | *tmp = *mpnt; |
282 | pol = mpol_copy(vma_policy(mpnt)); | 282 | pol = mpol_dup(vma_policy(mpnt)); |
283 | retval = PTR_ERR(pol); | 283 | retval = PTR_ERR(pol); |
284 | if (IS_ERR(pol)) | 284 | if (IS_ERR(pol)) |
285 | goto fail_nomem_policy; | 285 | goto fail_nomem_policy; |
@@ -1116,7 +1116,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1116 | p->audit_context = NULL; | 1116 | p->audit_context = NULL; |
1117 | cgroup_fork(p); | 1117 | cgroup_fork(p); |
1118 | #ifdef CONFIG_NUMA | 1118 | #ifdef CONFIG_NUMA |
1119 | p->mempolicy = mpol_copy(p->mempolicy); | 1119 | p->mempolicy = mpol_dup(p->mempolicy); |
1120 | if (IS_ERR(p->mempolicy)) { | 1120 | if (IS_ERR(p->mempolicy)) { |
1121 | retval = PTR_ERR(p->mempolicy); | 1121 | retval = PTR_ERR(p->mempolicy); |
1122 | p->mempolicy = NULL; | 1122 | p->mempolicy = NULL; |
@@ -1374,7 +1374,7 @@ bad_fork_cleanup_security: | |||
1374 | security_task_free(p); | 1374 | security_task_free(p); |
1375 | bad_fork_cleanup_policy: | 1375 | bad_fork_cleanup_policy: |
1376 | #ifdef CONFIG_NUMA | 1376 | #ifdef CONFIG_NUMA |
1377 | mpol_free(p->mempolicy); | 1377 | mpol_put(p->mempolicy); |
1378 | bad_fork_cleanup_cgroup: | 1378 | bad_fork_cleanup_cgroup: |
1379 | #endif | 1379 | #endif |
1380 | cgroup_exit(p, cgroup_callbacks_done); | 1380 | cgroup_exit(p, cgroup_callbacks_done); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f78777abe769..e379ef0e9c20 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1080,8 +1080,19 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base) | |||
1080 | * If the timer was rearmed on another CPU, reprogram | 1080 | * If the timer was rearmed on another CPU, reprogram |
1081 | * the event device. | 1081 | * the event device. |
1082 | */ | 1082 | */ |
1083 | if (timer->base->first == &timer->node) | 1083 | struct hrtimer_clock_base *base = timer->base; |
1084 | hrtimer_reprogram(timer, timer->base); | 1084 | |
1085 | if (base->first == &timer->node && | ||
1086 | hrtimer_reprogram(timer, base)) { | ||
1087 | /* | ||
1088 | * Timer is expired. Thus move it from tree to | ||
1089 | * pending list again. | ||
1090 | */ | ||
1091 | __remove_hrtimer(timer, base, | ||
1092 | HRTIMER_STATE_PENDING, 0); | ||
1093 | list_add_tail(&timer->cb_entry, | ||
1094 | &base->cpu_base->cb_pending); | ||
1095 | } | ||
1085 | } | 1096 | } |
1086 | } | 1097 | } |
1087 | spin_unlock_irq(&cpu_base->lock); | 1098 | spin_unlock_irq(&cpu_base->lock); |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 6782dce93d01..cb85c79989b4 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -1405,6 +1405,9 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
1405 | VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER); | 1405 | VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER); |
1406 | VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES); | 1406 | VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES); |
1407 | VMCOREINFO_NUMBER(NR_FREE_PAGES); | 1407 | VMCOREINFO_NUMBER(NR_FREE_PAGES); |
1408 | VMCOREINFO_NUMBER(PG_lru); | ||
1409 | VMCOREINFO_NUMBER(PG_private); | ||
1410 | VMCOREINFO_NUMBER(PG_swapcache); | ||
1408 | 1411 | ||
1409 | arch_crash_save_vmcoreinfo(); | 1412 | arch_crash_save_vmcoreinfo(); |
1410 | 1413 | ||
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index fcfb580c3afc..1e0250cb9486 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -72,6 +72,18 @@ DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */ | |||
72 | DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ | 72 | DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ |
73 | static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; | 73 | static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; |
74 | 74 | ||
75 | /* | ||
76 | * Normally, functions that we'd want to prohibit kprobes in, are marked | ||
77 | * __kprobes. But, there are cases where such functions already belong to | ||
78 | * a different section (__sched for preempt_schedule) | ||
79 | * | ||
80 | * For such cases, we now have a blacklist | ||
81 | */ | ||
82 | struct kprobe_blackpoint kprobe_blacklist[] = { | ||
83 | {"preempt_schedule",}, | ||
84 | {NULL} /* Terminator */ | ||
85 | }; | ||
86 | |||
75 | #ifdef __ARCH_WANT_KPROBES_INSN_SLOT | 87 | #ifdef __ARCH_WANT_KPROBES_INSN_SLOT |
76 | /* | 88 | /* |
77 | * kprobe->ainsn.insn points to the copy of the instruction to be | 89 | * kprobe->ainsn.insn points to the copy of the instruction to be |
@@ -417,6 +429,21 @@ static inline void free_rp_inst(struct kretprobe *rp) | |||
417 | } | 429 | } |
418 | } | 430 | } |
419 | 431 | ||
432 | static void __kprobes cleanup_rp_inst(struct kretprobe *rp) | ||
433 | { | ||
434 | unsigned long flags; | ||
435 | struct kretprobe_instance *ri; | ||
436 | struct hlist_node *pos, *next; | ||
437 | /* No race here */ | ||
438 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
439 | hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) { | ||
440 | ri->rp = NULL; | ||
441 | hlist_del(&ri->uflist); | ||
442 | } | ||
443 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
444 | free_rp_inst(rp); | ||
445 | } | ||
446 | |||
420 | /* | 447 | /* |
421 | * Keep all fields in the kprobe consistent | 448 | * Keep all fields in the kprobe consistent |
422 | */ | 449 | */ |
@@ -492,9 +519,22 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p, | |||
492 | 519 | ||
493 | static int __kprobes in_kprobes_functions(unsigned long addr) | 520 | static int __kprobes in_kprobes_functions(unsigned long addr) |
494 | { | 521 | { |
522 | struct kprobe_blackpoint *kb; | ||
523 | |||
495 | if (addr >= (unsigned long)__kprobes_text_start && | 524 | if (addr >= (unsigned long)__kprobes_text_start && |
496 | addr < (unsigned long)__kprobes_text_end) | 525 | addr < (unsigned long)__kprobes_text_end) |
497 | return -EINVAL; | 526 | return -EINVAL; |
527 | /* | ||
528 | * If there exists a kprobe_blacklist, verify and | ||
529 | * fail any probe registration in the prohibited area | ||
530 | */ | ||
531 | for (kb = kprobe_blacklist; kb->name != NULL; kb++) { | ||
532 | if (kb->start_addr) { | ||
533 | if (addr >= kb->start_addr && | ||
534 | addr < (kb->start_addr + kb->range)) | ||
535 | return -EINVAL; | ||
536 | } | ||
537 | } | ||
498 | return 0; | 538 | return 0; |
499 | } | 539 | } |
500 | 540 | ||
@@ -555,6 +595,7 @@ static int __kprobes __register_kprobe(struct kprobe *p, | |||
555 | } | 595 | } |
556 | 596 | ||
557 | p->nmissed = 0; | 597 | p->nmissed = 0; |
598 | INIT_LIST_HEAD(&p->list); | ||
558 | mutex_lock(&kprobe_mutex); | 599 | mutex_lock(&kprobe_mutex); |
559 | old_p = get_kprobe(p->addr); | 600 | old_p = get_kprobe(p->addr); |
560 | if (old_p) { | 601 | if (old_p) { |
@@ -581,35 +622,28 @@ out: | |||
581 | return ret; | 622 | return ret; |
582 | } | 623 | } |
583 | 624 | ||
584 | int __kprobes register_kprobe(struct kprobe *p) | 625 | /* |
585 | { | 626 | * Unregister a kprobe without a scheduler synchronization. |
586 | return __register_kprobe(p, (unsigned long)__builtin_return_address(0)); | 627 | */ |
587 | } | 628 | static int __kprobes __unregister_kprobe_top(struct kprobe *p) |
588 | |||
589 | void __kprobes unregister_kprobe(struct kprobe *p) | ||
590 | { | 629 | { |
591 | struct module *mod; | ||
592 | struct kprobe *old_p, *list_p; | 630 | struct kprobe *old_p, *list_p; |
593 | int cleanup_p; | ||
594 | 631 | ||
595 | mutex_lock(&kprobe_mutex); | ||
596 | old_p = get_kprobe(p->addr); | 632 | old_p = get_kprobe(p->addr); |
597 | if (unlikely(!old_p)) { | 633 | if (unlikely(!old_p)) |
598 | mutex_unlock(&kprobe_mutex); | 634 | return -EINVAL; |
599 | return; | 635 | |
600 | } | ||
601 | if (p != old_p) { | 636 | if (p != old_p) { |
602 | list_for_each_entry_rcu(list_p, &old_p->list, list) | 637 | list_for_each_entry_rcu(list_p, &old_p->list, list) |
603 | if (list_p == p) | 638 | if (list_p == p) |
604 | /* kprobe p is a valid probe */ | 639 | /* kprobe p is a valid probe */ |
605 | goto valid_p; | 640 | goto valid_p; |
606 | mutex_unlock(&kprobe_mutex); | 641 | return -EINVAL; |
607 | return; | ||
608 | } | 642 | } |
609 | valid_p: | 643 | valid_p: |
610 | if (old_p == p || | 644 | if (old_p == p || |
611 | (old_p->pre_handler == aggr_pre_handler && | 645 | (old_p->pre_handler == aggr_pre_handler && |
612 | p->list.next == &old_p->list && p->list.prev == &old_p->list)) { | 646 | list_is_singular(&old_p->list))) { |
613 | /* | 647 | /* |
614 | * Only probe on the hash list. Disarm only if kprobes are | 648 | * Only probe on the hash list. Disarm only if kprobes are |
615 | * enabled - otherwise, the breakpoint would already have | 649 | * enabled - otherwise, the breakpoint would already have |
@@ -618,43 +652,97 @@ valid_p: | |||
618 | if (kprobe_enabled) | 652 | if (kprobe_enabled) |
619 | arch_disarm_kprobe(p); | 653 | arch_disarm_kprobe(p); |
620 | hlist_del_rcu(&old_p->hlist); | 654 | hlist_del_rcu(&old_p->hlist); |
621 | cleanup_p = 1; | ||
622 | } else { | 655 | } else { |
656 | if (p->break_handler) | ||
657 | old_p->break_handler = NULL; | ||
658 | if (p->post_handler) { | ||
659 | list_for_each_entry_rcu(list_p, &old_p->list, list) { | ||
660 | if ((list_p != p) && (list_p->post_handler)) | ||
661 | goto noclean; | ||
662 | } | ||
663 | old_p->post_handler = NULL; | ||
664 | } | ||
665 | noclean: | ||
623 | list_del_rcu(&p->list); | 666 | list_del_rcu(&p->list); |
624 | cleanup_p = 0; | ||
625 | } | 667 | } |
668 | return 0; | ||
669 | } | ||
626 | 670 | ||
627 | mutex_unlock(&kprobe_mutex); | 671 | static void __kprobes __unregister_kprobe_bottom(struct kprobe *p) |
672 | { | ||
673 | struct module *mod; | ||
674 | struct kprobe *old_p; | ||
628 | 675 | ||
629 | synchronize_sched(); | ||
630 | if (p->mod_refcounted) { | 676 | if (p->mod_refcounted) { |
631 | mod = module_text_address((unsigned long)p->addr); | 677 | mod = module_text_address((unsigned long)p->addr); |
632 | if (mod) | 678 | if (mod) |
633 | module_put(mod); | 679 | module_put(mod); |
634 | } | 680 | } |
635 | 681 | ||
636 | if (cleanup_p) { | 682 | if (list_empty(&p->list) || list_is_singular(&p->list)) { |
637 | if (p != old_p) { | 683 | if (!list_empty(&p->list)) { |
638 | list_del_rcu(&p->list); | 684 | /* "p" is the last child of an aggr_kprobe */ |
685 | old_p = list_entry(p->list.next, struct kprobe, list); | ||
686 | list_del(&p->list); | ||
639 | kfree(old_p); | 687 | kfree(old_p); |
640 | } | 688 | } |
641 | arch_remove_kprobe(p); | 689 | arch_remove_kprobe(p); |
642 | } else { | 690 | } |
643 | mutex_lock(&kprobe_mutex); | 691 | } |
644 | if (p->break_handler) | 692 | |
645 | old_p->break_handler = NULL; | 693 | static int __register_kprobes(struct kprobe **kps, int num, |
646 | if (p->post_handler){ | 694 | unsigned long called_from) |
647 | list_for_each_entry_rcu(list_p, &old_p->list, list){ | 695 | { |
648 | if (list_p->post_handler){ | 696 | int i, ret = 0; |
649 | cleanup_p = 2; | 697 | |
650 | break; | 698 | if (num <= 0) |
651 | } | 699 | return -EINVAL; |
652 | } | 700 | for (i = 0; i < num; i++) { |
653 | if (cleanup_p == 0) | 701 | ret = __register_kprobe(kps[i], called_from); |
654 | old_p->post_handler = NULL; | 702 | if (ret < 0 && i > 0) { |
703 | unregister_kprobes(kps, i); | ||
704 | break; | ||
655 | } | 705 | } |
656 | mutex_unlock(&kprobe_mutex); | ||
657 | } | 706 | } |
707 | return ret; | ||
708 | } | ||
709 | |||
710 | /* | ||
711 | * Registration and unregistration functions for kprobe. | ||
712 | */ | ||
713 | int __kprobes register_kprobe(struct kprobe *p) | ||
714 | { | ||
715 | return __register_kprobes(&p, 1, | ||
716 | (unsigned long)__builtin_return_address(0)); | ||
717 | } | ||
718 | |||
719 | void __kprobes unregister_kprobe(struct kprobe *p) | ||
720 | { | ||
721 | unregister_kprobes(&p, 1); | ||
722 | } | ||
723 | |||
724 | int __kprobes register_kprobes(struct kprobe **kps, int num) | ||
725 | { | ||
726 | return __register_kprobes(kps, num, | ||
727 | (unsigned long)__builtin_return_address(0)); | ||
728 | } | ||
729 | |||
730 | void __kprobes unregister_kprobes(struct kprobe **kps, int num) | ||
731 | { | ||
732 | int i; | ||
733 | |||
734 | if (num <= 0) | ||
735 | return; | ||
736 | mutex_lock(&kprobe_mutex); | ||
737 | for (i = 0; i < num; i++) | ||
738 | if (__unregister_kprobe_top(kps[i]) < 0) | ||
739 | kps[i]->addr = NULL; | ||
740 | mutex_unlock(&kprobe_mutex); | ||
741 | |||
742 | synchronize_sched(); | ||
743 | for (i = 0; i < num; i++) | ||
744 | if (kps[i]->addr) | ||
745 | __unregister_kprobe_bottom(kps[i]); | ||
658 | } | 746 | } |
659 | 747 | ||
660 | static struct notifier_block kprobe_exceptions_nb = { | 748 | static struct notifier_block kprobe_exceptions_nb = { |
@@ -667,24 +755,69 @@ unsigned long __weak arch_deref_entry_point(void *entry) | |||
667 | return (unsigned long)entry; | 755 | return (unsigned long)entry; |
668 | } | 756 | } |
669 | 757 | ||
670 | int __kprobes register_jprobe(struct jprobe *jp) | 758 | static int __register_jprobes(struct jprobe **jps, int num, |
759 | unsigned long called_from) | ||
671 | { | 760 | { |
672 | unsigned long addr = arch_deref_entry_point(jp->entry); | 761 | struct jprobe *jp; |
762 | int ret = 0, i; | ||
673 | 763 | ||
674 | if (!kernel_text_address(addr)) | 764 | if (num <= 0) |
675 | return -EINVAL; | 765 | return -EINVAL; |
766 | for (i = 0; i < num; i++) { | ||
767 | unsigned long addr; | ||
768 | jp = jps[i]; | ||
769 | addr = arch_deref_entry_point(jp->entry); | ||
770 | |||
771 | if (!kernel_text_address(addr)) | ||
772 | ret = -EINVAL; | ||
773 | else { | ||
774 | /* Todo: Verify probepoint is a function entry point */ | ||
775 | jp->kp.pre_handler = setjmp_pre_handler; | ||
776 | jp->kp.break_handler = longjmp_break_handler; | ||
777 | ret = __register_kprobe(&jp->kp, called_from); | ||
778 | } | ||
779 | if (ret < 0 && i > 0) { | ||
780 | unregister_jprobes(jps, i); | ||
781 | break; | ||
782 | } | ||
783 | } | ||
784 | return ret; | ||
785 | } | ||
676 | 786 | ||
677 | /* Todo: Verify probepoint is a function entry point */ | 787 | int __kprobes register_jprobe(struct jprobe *jp) |
678 | jp->kp.pre_handler = setjmp_pre_handler; | 788 | { |
679 | jp->kp.break_handler = longjmp_break_handler; | 789 | return __register_jprobes(&jp, 1, |
680 | |||
681 | return __register_kprobe(&jp->kp, | ||
682 | (unsigned long)__builtin_return_address(0)); | 790 | (unsigned long)__builtin_return_address(0)); |
683 | } | 791 | } |
684 | 792 | ||
685 | void __kprobes unregister_jprobe(struct jprobe *jp) | 793 | void __kprobes unregister_jprobe(struct jprobe *jp) |
686 | { | 794 | { |
687 | unregister_kprobe(&jp->kp); | 795 | unregister_jprobes(&jp, 1); |
796 | } | ||
797 | |||
798 | int __kprobes register_jprobes(struct jprobe **jps, int num) | ||
799 | { | ||
800 | return __register_jprobes(jps, num, | ||
801 | (unsigned long)__builtin_return_address(0)); | ||
802 | } | ||
803 | |||
804 | void __kprobes unregister_jprobes(struct jprobe **jps, int num) | ||
805 | { | ||
806 | int i; | ||
807 | |||
808 | if (num <= 0) | ||
809 | return; | ||
810 | mutex_lock(&kprobe_mutex); | ||
811 | for (i = 0; i < num; i++) | ||
812 | if (__unregister_kprobe_top(&jps[i]->kp) < 0) | ||
813 | jps[i]->kp.addr = NULL; | ||
814 | mutex_unlock(&kprobe_mutex); | ||
815 | |||
816 | synchronize_sched(); | ||
817 | for (i = 0; i < num; i++) { | ||
818 | if (jps[i]->kp.addr) | ||
819 | __unregister_kprobe_bottom(&jps[i]->kp); | ||
820 | } | ||
688 | } | 821 | } |
689 | 822 | ||
690 | #ifdef CONFIG_KRETPROBES | 823 | #ifdef CONFIG_KRETPROBES |
@@ -725,7 +858,8 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, | |||
725 | return 0; | 858 | return 0; |
726 | } | 859 | } |
727 | 860 | ||
728 | int __kprobes register_kretprobe(struct kretprobe *rp) | 861 | static int __kprobes __register_kretprobe(struct kretprobe *rp, |
862 | unsigned long called_from) | ||
729 | { | 863 | { |
730 | int ret = 0; | 864 | int ret = 0; |
731 | struct kretprobe_instance *inst; | 865 | struct kretprobe_instance *inst; |
@@ -771,46 +905,101 @@ int __kprobes register_kretprobe(struct kretprobe *rp) | |||
771 | 905 | ||
772 | rp->nmissed = 0; | 906 | rp->nmissed = 0; |
773 | /* Establish function entry probe point */ | 907 | /* Establish function entry probe point */ |
774 | if ((ret = __register_kprobe(&rp->kp, | 908 | ret = __register_kprobe(&rp->kp, called_from); |
775 | (unsigned long)__builtin_return_address(0))) != 0) | 909 | if (ret != 0) |
776 | free_rp_inst(rp); | 910 | free_rp_inst(rp); |
777 | return ret; | 911 | return ret; |
778 | } | 912 | } |
779 | 913 | ||
914 | static int __register_kretprobes(struct kretprobe **rps, int num, | ||
915 | unsigned long called_from) | ||
916 | { | ||
917 | int ret = 0, i; | ||
918 | |||
919 | if (num <= 0) | ||
920 | return -EINVAL; | ||
921 | for (i = 0; i < num; i++) { | ||
922 | ret = __register_kretprobe(rps[i], called_from); | ||
923 | if (ret < 0 && i > 0) { | ||
924 | unregister_kretprobes(rps, i); | ||
925 | break; | ||
926 | } | ||
927 | } | ||
928 | return ret; | ||
929 | } | ||
930 | |||
931 | int __kprobes register_kretprobe(struct kretprobe *rp) | ||
932 | { | ||
933 | return __register_kretprobes(&rp, 1, | ||
934 | (unsigned long)__builtin_return_address(0)); | ||
935 | } | ||
936 | |||
937 | void __kprobes unregister_kretprobe(struct kretprobe *rp) | ||
938 | { | ||
939 | unregister_kretprobes(&rp, 1); | ||
940 | } | ||
941 | |||
942 | int __kprobes register_kretprobes(struct kretprobe **rps, int num) | ||
943 | { | ||
944 | return __register_kretprobes(rps, num, | ||
945 | (unsigned long)__builtin_return_address(0)); | ||
946 | } | ||
947 | |||
948 | void __kprobes unregister_kretprobes(struct kretprobe **rps, int num) | ||
949 | { | ||
950 | int i; | ||
951 | |||
952 | if (num <= 0) | ||
953 | return; | ||
954 | mutex_lock(&kprobe_mutex); | ||
955 | for (i = 0; i < num; i++) | ||
956 | if (__unregister_kprobe_top(&rps[i]->kp) < 0) | ||
957 | rps[i]->kp.addr = NULL; | ||
958 | mutex_unlock(&kprobe_mutex); | ||
959 | |||
960 | synchronize_sched(); | ||
961 | for (i = 0; i < num; i++) { | ||
962 | if (rps[i]->kp.addr) { | ||
963 | __unregister_kprobe_bottom(&rps[i]->kp); | ||
964 | cleanup_rp_inst(rps[i]); | ||
965 | } | ||
966 | } | ||
967 | } | ||
968 | |||
780 | #else /* CONFIG_KRETPROBES */ | 969 | #else /* CONFIG_KRETPROBES */ |
781 | int __kprobes register_kretprobe(struct kretprobe *rp) | 970 | int __kprobes register_kretprobe(struct kretprobe *rp) |
782 | { | 971 | { |
783 | return -ENOSYS; | 972 | return -ENOSYS; |
784 | } | 973 | } |
785 | 974 | ||
786 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, | 975 | int __kprobes register_kretprobes(struct kretprobe **rps, int num) |
787 | struct pt_regs *regs) | ||
788 | { | 976 | { |
789 | return 0; | 977 | return -ENOSYS; |
790 | } | 978 | } |
791 | #endif /* CONFIG_KRETPROBES */ | ||
792 | |||
793 | void __kprobes unregister_kretprobe(struct kretprobe *rp) | 979 | void __kprobes unregister_kretprobe(struct kretprobe *rp) |
794 | { | 980 | { |
795 | unsigned long flags; | 981 | } |
796 | struct kretprobe_instance *ri; | ||
797 | struct hlist_node *pos, *next; | ||
798 | 982 | ||
799 | unregister_kprobe(&rp->kp); | 983 | void __kprobes unregister_kretprobes(struct kretprobe **rps, int num) |
984 | { | ||
985 | } | ||
800 | 986 | ||
801 | /* No race here */ | 987 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, |
802 | spin_lock_irqsave(&kretprobe_lock, flags); | 988 | struct pt_regs *regs) |
803 | hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) { | 989 | { |
804 | ri->rp = NULL; | 990 | return 0; |
805 | hlist_del(&ri->uflist); | ||
806 | } | ||
807 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
808 | free_rp_inst(rp); | ||
809 | } | 991 | } |
810 | 992 | ||
993 | #endif /* CONFIG_KRETPROBES */ | ||
994 | |||
811 | static int __init init_kprobes(void) | 995 | static int __init init_kprobes(void) |
812 | { | 996 | { |
813 | int i, err = 0; | 997 | int i, err = 0; |
998 | unsigned long offset = 0, size = 0; | ||
999 | char *modname, namebuf[128]; | ||
1000 | const char *symbol_name; | ||
1001 | void *addr; | ||
1002 | struct kprobe_blackpoint *kb; | ||
814 | 1003 | ||
815 | /* FIXME allocate the probe table, currently defined statically */ | 1004 | /* FIXME allocate the probe table, currently defined statically */ |
816 | /* initialize all list heads */ | 1005 | /* initialize all list heads */ |
@@ -819,6 +1008,28 @@ static int __init init_kprobes(void) | |||
819 | INIT_HLIST_HEAD(&kretprobe_inst_table[i]); | 1008 | INIT_HLIST_HEAD(&kretprobe_inst_table[i]); |
820 | } | 1009 | } |
821 | 1010 | ||
1011 | /* | ||
1012 | * Lookup and populate the kprobe_blacklist. | ||
1013 | * | ||
1014 | * Unlike the kretprobe blacklist, we'll need to determine | ||
1015 | * the range of addresses that belong to the said functions, | ||
1016 | * since a kprobe need not necessarily be at the beginning | ||
1017 | * of a function. | ||
1018 | */ | ||
1019 | for (kb = kprobe_blacklist; kb->name != NULL; kb++) { | ||
1020 | kprobe_lookup_name(kb->name, addr); | ||
1021 | if (!addr) | ||
1022 | continue; | ||
1023 | |||
1024 | kb->start_addr = (unsigned long)addr; | ||
1025 | symbol_name = kallsyms_lookup(kb->start_addr, | ||
1026 | &size, &offset, &modname, namebuf); | ||
1027 | if (!symbol_name) | ||
1028 | kb->range = 0; | ||
1029 | else | ||
1030 | kb->range = size; | ||
1031 | } | ||
1032 | |||
822 | if (kretprobe_blacklist_size) { | 1033 | if (kretprobe_blacklist_size) { |
823 | /* lookup the function address from its name */ | 1034 | /* lookup the function address from its name */ |
824 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { | 1035 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { |
@@ -1066,8 +1277,12 @@ module_init(init_kprobes); | |||
1066 | 1277 | ||
1067 | EXPORT_SYMBOL_GPL(register_kprobe); | 1278 | EXPORT_SYMBOL_GPL(register_kprobe); |
1068 | EXPORT_SYMBOL_GPL(unregister_kprobe); | 1279 | EXPORT_SYMBOL_GPL(unregister_kprobe); |
1280 | EXPORT_SYMBOL_GPL(register_kprobes); | ||
1281 | EXPORT_SYMBOL_GPL(unregister_kprobes); | ||
1069 | EXPORT_SYMBOL_GPL(register_jprobe); | 1282 | EXPORT_SYMBOL_GPL(register_jprobe); |
1070 | EXPORT_SYMBOL_GPL(unregister_jprobe); | 1283 | EXPORT_SYMBOL_GPL(unregister_jprobe); |
1284 | EXPORT_SYMBOL_GPL(register_jprobes); | ||
1285 | EXPORT_SYMBOL_GPL(unregister_jprobes); | ||
1071 | #ifdef CONFIG_KPROBES | 1286 | #ifdef CONFIG_KPROBES |
1072 | EXPORT_SYMBOL_GPL(jprobe_return); | 1287 | EXPORT_SYMBOL_GPL(jprobe_return); |
1073 | #endif | 1288 | #endif |
@@ -1075,4 +1290,6 @@ EXPORT_SYMBOL_GPL(jprobe_return); | |||
1075 | #ifdef CONFIG_KPROBES | 1290 | #ifdef CONFIG_KPROBES |
1076 | EXPORT_SYMBOL_GPL(register_kretprobe); | 1291 | EXPORT_SYMBOL_GPL(register_kretprobe); |
1077 | EXPORT_SYMBOL_GPL(unregister_kretprobe); | 1292 | EXPORT_SYMBOL_GPL(unregister_kretprobe); |
1293 | EXPORT_SYMBOL_GPL(register_kretprobes); | ||
1294 | EXPORT_SYMBOL_GPL(unregister_kretprobes); | ||
1078 | #endif | 1295 | #endif |
diff --git a/kernel/power/console.c b/kernel/power/console.c index 89bcf4973ee5..b8628be2a465 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
@@ -7,17 +7,39 @@ | |||
7 | #include <linux/vt_kern.h> | 7 | #include <linux/vt_kern.h> |
8 | #include <linux/kbd_kern.h> | 8 | #include <linux/kbd_kern.h> |
9 | #include <linux/console.h> | 9 | #include <linux/console.h> |
10 | #include <linux/module.h> | ||
10 | #include "power.h" | 11 | #include "power.h" |
11 | 12 | ||
12 | #if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) | 13 | #if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) |
13 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | 14 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) |
14 | 15 | ||
15 | static int orig_fgconsole, orig_kmsg; | 16 | static int orig_fgconsole, orig_kmsg; |
17 | static int disable_vt_switch; | ||
18 | |||
19 | /* | ||
20 | * Normally during a suspend, we allocate a new console and switch to it. | ||
21 | * When we resume, we switch back to the original console. This switch | ||
22 | * can be slow, so on systems where the framebuffer can handle restoration | ||
23 | * of video registers anyways, there's little point in doing the console | ||
24 | * switch. This function allows you to disable it by passing it '0'. | ||
25 | */ | ||
26 | void pm_set_vt_switch(int do_switch) | ||
27 | { | ||
28 | acquire_console_sem(); | ||
29 | disable_vt_switch = !do_switch; | ||
30 | release_console_sem(); | ||
31 | } | ||
32 | EXPORT_SYMBOL(pm_set_vt_switch); | ||
16 | 33 | ||
17 | int pm_prepare_console(void) | 34 | int pm_prepare_console(void) |
18 | { | 35 | { |
19 | acquire_console_sem(); | 36 | acquire_console_sem(); |
20 | 37 | ||
38 | if (disable_vt_switch) { | ||
39 | release_console_sem(); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
21 | orig_fgconsole = fg_console; | 43 | orig_fgconsole = fg_console; |
22 | 44 | ||
23 | if (vc_allocate(SUSPEND_CONSOLE)) { | 45 | if (vc_allocate(SUSPEND_CONSOLE)) { |
@@ -50,9 +72,12 @@ int pm_prepare_console(void) | |||
50 | void pm_restore_console(void) | 72 | void pm_restore_console(void) |
51 | { | 73 | { |
52 | acquire_console_sem(); | 74 | acquire_console_sem(); |
75 | if (disable_vt_switch) { | ||
76 | release_console_sem(); | ||
77 | return; | ||
78 | } | ||
53 | set_console(orig_fgconsole); | 79 | set_console(orig_fgconsole); |
54 | release_console_sem(); | 80 | release_console_sem(); |
55 | kmsg_redirect = orig_kmsg; | 81 | kmsg_redirect = orig_kmsg; |
56 | return; | ||
57 | } | 82 | } |
58 | #endif | 83 | #endif |
diff --git a/kernel/sys.c b/kernel/sys.c index 6a0cc71ee88d..f2a451366953 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1632,10 +1632,9 @@ asmlinkage long sys_umask(int mask) | |||
1632 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 1632 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, |
1633 | unsigned long arg4, unsigned long arg5) | 1633 | unsigned long arg4, unsigned long arg5) |
1634 | { | 1634 | { |
1635 | long error; | 1635 | long uninitialized_var(error); |
1636 | 1636 | ||
1637 | error = security_task_prctl(option, arg2, arg3, arg4, arg5); | 1637 | if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) |
1638 | if (error) | ||
1639 | return error; | 1638 | return error; |
1640 | 1639 | ||
1641 | switch (option) { | 1640 | switch (option) { |
@@ -1688,17 +1687,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1688 | error = -EINVAL; | 1687 | error = -EINVAL; |
1689 | break; | 1688 | break; |
1690 | 1689 | ||
1691 | case PR_GET_KEEPCAPS: | ||
1692 | if (current->keep_capabilities) | ||
1693 | error = 1; | ||
1694 | break; | ||
1695 | case PR_SET_KEEPCAPS: | ||
1696 | if (arg2 != 0 && arg2 != 1) { | ||
1697 | error = -EINVAL; | ||
1698 | break; | ||
1699 | } | ||
1700 | current->keep_capabilities = arg2; | ||
1701 | break; | ||
1702 | case PR_SET_NAME: { | 1690 | case PR_SET_NAME: { |
1703 | struct task_struct *me = current; | 1691 | struct task_struct *me = current; |
1704 | unsigned char ncomm[sizeof(me->comm)]; | 1692 | unsigned char ncomm[sizeof(me->comm)]; |
@@ -1732,17 +1720,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1732 | case PR_SET_SECCOMP: | 1720 | case PR_SET_SECCOMP: |
1733 | error = prctl_set_seccomp(arg2); | 1721 | error = prctl_set_seccomp(arg2); |
1734 | break; | 1722 | break; |
1735 | |||
1736 | case PR_CAPBSET_READ: | ||
1737 | if (!cap_valid(arg2)) | ||
1738 | return -EINVAL; | ||
1739 | return !!cap_raised(current->cap_bset, arg2); | ||
1740 | case PR_CAPBSET_DROP: | ||
1741 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
1742 | return cap_prctl_drop(arg2); | ||
1743 | #else | ||
1744 | return -EINVAL; | ||
1745 | #endif | ||
1746 | case PR_GET_TSC: | 1723 | case PR_GET_TSC: |
1747 | error = GET_TSC_CTL(arg2); | 1724 | error = GET_TSC_CTL(arg2); |
1748 | break; | 1725 | break; |