diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-04-17 04:16:58 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-24 04:02:56 -0400 |
commit | be8f274323c26ddc7e6fd6c44254b7abcdbe6389 (patch) | |
tree | 01988f9374f3f8ad257d38b7f636efa297455b90 | |
parent | 6a5022a56ac37da7bffece043331a101ed0040b1 (diff) |
kprobes: Prohibit probing on .entry.text code
.entry.text is a code area which is used for interrupt/syscall
entries, which includes many sensitive code.
Thus, it is better to prohibit probing on all of such code
instead of a part of that.
Since some symbols are already registered on kprobe blacklist,
this also removes them from the blacklist.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Jonathan Lebon <jlebon@redhat.com>
Cc: Seiji Aguchi <seiji.aguchi@hds.com>
Link: http://lkml.kernel.org/r/20140417081658.26341.57354.stgit@ltc230.yrl.intra.hitachi.co.jp
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/kernel/entry_32.S | 33 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 20 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes/core.c | 8 | ||||
-rw-r--r-- | include/linux/kprobes.h | 1 | ||||
-rw-r--r-- | kernel/kprobes.c | 13 |
5 files changed, 17 insertions, 58 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index a2a4f4697889..0ca5bf1697bb 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -315,10 +315,6 @@ ENTRY(ret_from_kernel_thread) | |||
315 | ENDPROC(ret_from_kernel_thread) | 315 | ENDPROC(ret_from_kernel_thread) |
316 | 316 | ||
317 | /* | 317 | /* |
318 | * Interrupt exit functions should be protected against kprobes | ||
319 | */ | ||
320 | .pushsection .kprobes.text, "ax" | ||
321 | /* | ||
322 | * Return to user mode is not as complex as all this looks, | 318 | * Return to user mode is not as complex as all this looks, |
323 | * but we want the default path for a system call return to | 319 | * but we want the default path for a system call return to |
324 | * go as quickly as possible which is why some of this is | 320 | * go as quickly as possible which is why some of this is |
@@ -372,10 +368,6 @@ need_resched: | |||
372 | END(resume_kernel) | 368 | END(resume_kernel) |
373 | #endif | 369 | #endif |
374 | CFI_ENDPROC | 370 | CFI_ENDPROC |
375 | /* | ||
376 | * End of kprobes section | ||
377 | */ | ||
378 | .popsection | ||
379 | 371 | ||
380 | /* SYSENTER_RETURN points to after the "sysenter" instruction in | 372 | /* SYSENTER_RETURN points to after the "sysenter" instruction in |
381 | the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ | 373 | the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ |
@@ -495,10 +487,6 @@ sysexit_audit: | |||
495 | PTGS_TO_GS_EX | 487 | PTGS_TO_GS_EX |
496 | ENDPROC(ia32_sysenter_target) | 488 | ENDPROC(ia32_sysenter_target) |
497 | 489 | ||
498 | /* | ||
499 | * syscall stub including irq exit should be protected against kprobes | ||
500 | */ | ||
501 | .pushsection .kprobes.text, "ax" | ||
502 | # system call handler stub | 490 | # system call handler stub |
503 | ENTRY(system_call) | 491 | ENTRY(system_call) |
504 | RING0_INT_FRAME # can't unwind into user space anyway | 492 | RING0_INT_FRAME # can't unwind into user space anyway |
@@ -691,10 +679,6 @@ syscall_badsys: | |||
691 | jmp resume_userspace | 679 | jmp resume_userspace |
692 | END(syscall_badsys) | 680 | END(syscall_badsys) |
693 | CFI_ENDPROC | 681 | CFI_ENDPROC |
694 | /* | ||
695 | * End of kprobes section | ||
696 | */ | ||
697 | .popsection | ||
698 | 682 | ||
699 | .macro FIXUP_ESPFIX_STACK | 683 | .macro FIXUP_ESPFIX_STACK |
700 | /* | 684 | /* |
@@ -781,10 +765,6 @@ common_interrupt: | |||
781 | ENDPROC(common_interrupt) | 765 | ENDPROC(common_interrupt) |
782 | CFI_ENDPROC | 766 | CFI_ENDPROC |
783 | 767 | ||
784 | /* | ||
785 | * Irq entries should be protected against kprobes | ||
786 | */ | ||
787 | .pushsection .kprobes.text, "ax" | ||
788 | #define BUILD_INTERRUPT3(name, nr, fn) \ | 768 | #define BUILD_INTERRUPT3(name, nr, fn) \ |
789 | ENTRY(name) \ | 769 | ENTRY(name) \ |
790 | RING0_INT_FRAME; \ | 770 | RING0_INT_FRAME; \ |
@@ -961,10 +941,6 @@ ENTRY(spurious_interrupt_bug) | |||
961 | jmp error_code | 941 | jmp error_code |
962 | CFI_ENDPROC | 942 | CFI_ENDPROC |
963 | END(spurious_interrupt_bug) | 943 | END(spurious_interrupt_bug) |
964 | /* | ||
965 | * End of kprobes section | ||
966 | */ | ||
967 | .popsection | ||
968 | 944 | ||
969 | #ifdef CONFIG_XEN | 945 | #ifdef CONFIG_XEN |
970 | /* Xen doesn't set %esp to be precisely what the normal sysenter | 946 | /* Xen doesn't set %esp to be precisely what the normal sysenter |
@@ -1239,11 +1215,6 @@ return_to_handler: | |||
1239 | jmp *%ecx | 1215 | jmp *%ecx |
1240 | #endif | 1216 | #endif |
1241 | 1217 | ||
1242 | /* | ||
1243 | * Some functions should be protected against kprobes | ||
1244 | */ | ||
1245 | .pushsection .kprobes.text, "ax" | ||
1246 | |||
1247 | #ifdef CONFIG_TRACING | 1218 | #ifdef CONFIG_TRACING |
1248 | ENTRY(trace_page_fault) | 1219 | ENTRY(trace_page_fault) |
1249 | RING0_EC_FRAME | 1220 | RING0_EC_FRAME |
@@ -1453,7 +1424,3 @@ ENTRY(async_page_fault) | |||
1453 | END(async_page_fault) | 1424 | END(async_page_fault) |
1454 | #endif | 1425 | #endif |
1455 | 1426 | ||
1456 | /* | ||
1457 | * End of kprobes section | ||
1458 | */ | ||
1459 | .popsection | ||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 1e96c3628bf2..43bb38951660 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -487,8 +487,6 @@ ENDPROC(native_usergs_sysret64) | |||
487 | TRACE_IRQS_OFF | 487 | TRACE_IRQS_OFF |
488 | .endm | 488 | .endm |
489 | 489 | ||
490 | /* save complete stack frame */ | ||
491 | .pushsection .kprobes.text, "ax" | ||
492 | ENTRY(save_paranoid) | 490 | ENTRY(save_paranoid) |
493 | XCPT_FRAME 1 RDI+8 | 491 | XCPT_FRAME 1 RDI+8 |
494 | cld | 492 | cld |
@@ -517,7 +515,6 @@ ENTRY(save_paranoid) | |||
517 | 1: ret | 515 | 1: ret |
518 | CFI_ENDPROC | 516 | CFI_ENDPROC |
519 | END(save_paranoid) | 517 | END(save_paranoid) |
520 | .popsection | ||
521 | 518 | ||
522 | /* | 519 | /* |
523 | * A newly forked process directly context switches into this address. | 520 | * A newly forked process directly context switches into this address. |
@@ -975,10 +972,6 @@ END(interrupt) | |||
975 | call \func | 972 | call \func |
976 | .endm | 973 | .endm |
977 | 974 | ||
978 | /* | ||
979 | * Interrupt entry/exit should be protected against kprobes | ||
980 | */ | ||
981 | .pushsection .kprobes.text, "ax" | ||
982 | /* | 975 | /* |
983 | * The interrupt stubs push (~vector+0x80) onto the stack and | 976 | * The interrupt stubs push (~vector+0x80) onto the stack and |
984 | * then jump to common_interrupt. | 977 | * then jump to common_interrupt. |
@@ -1113,10 +1106,6 @@ ENTRY(retint_kernel) | |||
1113 | 1106 | ||
1114 | CFI_ENDPROC | 1107 | CFI_ENDPROC |
1115 | END(common_interrupt) | 1108 | END(common_interrupt) |
1116 | /* | ||
1117 | * End of kprobes section | ||
1118 | */ | ||
1119 | .popsection | ||
1120 | 1109 | ||
1121 | /* | 1110 | /* |
1122 | * APIC interrupts. | 1111 | * APIC interrupts. |
@@ -1477,11 +1466,6 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ | |||
1477 | hyperv_callback_vector hyperv_vector_handler | 1466 | hyperv_callback_vector hyperv_vector_handler |
1478 | #endif /* CONFIG_HYPERV */ | 1467 | #endif /* CONFIG_HYPERV */ |
1479 | 1468 | ||
1480 | /* | ||
1481 | * Some functions should be protected against kprobes | ||
1482 | */ | ||
1483 | .pushsection .kprobes.text, "ax" | ||
1484 | |||
1485 | paranoidzeroentry_ist debug do_debug DEBUG_STACK | 1469 | paranoidzeroentry_ist debug do_debug DEBUG_STACK |
1486 | paranoidzeroentry_ist int3 do_int3 DEBUG_STACK | 1470 | paranoidzeroentry_ist int3 do_int3 DEBUG_STACK |
1487 | paranoiderrorentry stack_segment do_stack_segment | 1471 | paranoiderrorentry stack_segment do_stack_segment |
@@ -1898,7 +1882,3 @@ ENTRY(ignore_sysret) | |||
1898 | CFI_ENDPROC | 1882 | CFI_ENDPROC |
1899 | END(ignore_sysret) | 1883 | END(ignore_sysret) |
1900 | 1884 | ||
1901 | /* | ||
1902 | * End of kprobes section | ||
1903 | */ | ||
1904 | .popsection | ||
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index da7bdaa3ce15..7751b3dee53a 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -1065,6 +1065,14 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
1065 | return 0; | 1065 | return 0; |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | bool arch_within_kprobe_blacklist(unsigned long addr) | ||
1069 | { | ||
1070 | return (addr >= (unsigned long)__kprobes_text_start && | ||
1071 | addr < (unsigned long)__kprobes_text_end) || | ||
1072 | (addr >= (unsigned long)__entry_text_start && | ||
1073 | addr < (unsigned long)__entry_text_end); | ||
1074 | } | ||
1075 | |||
1068 | int __init arch_init_kprobes(void) | 1076 | int __init arch_init_kprobes(void) |
1069 | { | 1077 | { |
1070 | return 0; | 1078 | return 0; |
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 925eaf28fca9..cdf9251f8249 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
@@ -265,6 +265,7 @@ extern void arch_disarm_kprobe(struct kprobe *p); | |||
265 | extern int arch_init_kprobes(void); | 265 | extern int arch_init_kprobes(void); |
266 | extern void show_registers(struct pt_regs *regs); | 266 | extern void show_registers(struct pt_regs *regs); |
267 | extern void kprobes_inc_nmissed_count(struct kprobe *p); | 267 | extern void kprobes_inc_nmissed_count(struct kprobe *p); |
268 | extern bool arch_within_kprobe_blacklist(unsigned long addr); | ||
268 | 269 | ||
269 | struct kprobe_insn_cache { | 270 | struct kprobe_insn_cache { |
270 | struct mutex mutex; | 271 | struct mutex mutex; |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ceeadfcabb76..5b5ac76671e7 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -96,9 +96,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash) | |||
96 | static struct kprobe_blackpoint kprobe_blacklist[] = { | 96 | static struct kprobe_blackpoint kprobe_blacklist[] = { |
97 | {"preempt_schedule",}, | 97 | {"preempt_schedule",}, |
98 | {"native_get_debugreg",}, | 98 | {"native_get_debugreg",}, |
99 | {"irq_entries_start",}, | ||
100 | {"common_interrupt",}, | ||
101 | {"mcount",}, /* mcount can be called from everywhere */ | ||
102 | {NULL} /* Terminator */ | 99 | {NULL} /* Terminator */ |
103 | }; | 100 | }; |
104 | 101 | ||
@@ -1324,12 +1321,18 @@ out: | |||
1324 | return ret; | 1321 | return ret; |
1325 | } | 1322 | } |
1326 | 1323 | ||
1324 | bool __weak arch_within_kprobe_blacklist(unsigned long addr) | ||
1325 | { | ||
1326 | /* The __kprobes marked functions and entry code must not be probed */ | ||
1327 | return addr >= (unsigned long)__kprobes_text_start && | ||
1328 | addr < (unsigned long)__kprobes_text_end; | ||
1329 | } | ||
1330 | |||
1327 | static int __kprobes in_kprobes_functions(unsigned long addr) | 1331 | static int __kprobes in_kprobes_functions(unsigned long addr) |
1328 | { | 1332 | { |
1329 | struct kprobe_blackpoint *kb; | 1333 | struct kprobe_blackpoint *kb; |
1330 | 1334 | ||
1331 | if (addr >= (unsigned long)__kprobes_text_start && | 1335 | if (arch_within_kprobe_blacklist(addr)) |
1332 | addr < (unsigned long)__kprobes_text_end) | ||
1333 | return -EINVAL; | 1336 | return -EINVAL; |
1334 | /* | 1337 | /* |
1335 | * If there exists a kprobe_blacklist, verify and | 1338 | * If there exists a kprobe_blacklist, verify and |