Commit be8f2743 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Ingo Molnar

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: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: default avatarSteven 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.jpSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 6a5022a5
...@@ -314,10 +314,6 @@ ENTRY(ret_from_kernel_thread) ...@@ -314,10 +314,6 @@ ENTRY(ret_from_kernel_thread)
CFI_ENDPROC CFI_ENDPROC
ENDPROC(ret_from_kernel_thread) ENDPROC(ret_from_kernel_thread)
/*
* Interrupt exit functions should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
/* /*
* Return to user mode is not as complex as all this looks, * Return to user mode is not as complex as all this looks,
* but we want the default path for a system call return to * but we want the default path for a system call return to
...@@ -372,10 +368,6 @@ need_resched: ...@@ -372,10 +368,6 @@ need_resched:
END(resume_kernel) END(resume_kernel)
#endif #endif
CFI_ENDPROC CFI_ENDPROC
/*
* End of kprobes section
*/
.popsection
/* SYSENTER_RETURN points to after the "sysenter" instruction in /* SYSENTER_RETURN points to after the "sysenter" instruction in
the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
...@@ -495,10 +487,6 @@ sysexit_audit: ...@@ -495,10 +487,6 @@ sysexit_audit:
PTGS_TO_GS_EX PTGS_TO_GS_EX
ENDPROC(ia32_sysenter_target) ENDPROC(ia32_sysenter_target)
/*
* syscall stub including irq exit should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
# system call handler stub # system call handler stub
ENTRY(system_call) ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway RING0_INT_FRAME # can't unwind into user space anyway
...@@ -691,10 +679,6 @@ syscall_badsys: ...@@ -691,10 +679,6 @@ syscall_badsys:
jmp resume_userspace jmp resume_userspace
END(syscall_badsys) END(syscall_badsys)
CFI_ENDPROC CFI_ENDPROC
/*
* End of kprobes section
*/
.popsection
.macro FIXUP_ESPFIX_STACK .macro FIXUP_ESPFIX_STACK
/* /*
...@@ -781,10 +765,6 @@ common_interrupt: ...@@ -781,10 +765,6 @@ common_interrupt:
ENDPROC(common_interrupt) ENDPROC(common_interrupt)
CFI_ENDPROC CFI_ENDPROC
/*
* Irq entries should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
#define BUILD_INTERRUPT3(name, nr, fn) \ #define BUILD_INTERRUPT3(name, nr, fn) \
ENTRY(name) \ ENTRY(name) \
RING0_INT_FRAME; \ RING0_INT_FRAME; \
...@@ -961,10 +941,6 @@ ENTRY(spurious_interrupt_bug) ...@@ -961,10 +941,6 @@ ENTRY(spurious_interrupt_bug)
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
END(spurious_interrupt_bug) END(spurious_interrupt_bug)
/*
* End of kprobes section
*/
.popsection
#ifdef CONFIG_XEN #ifdef CONFIG_XEN
/* Xen doesn't set %esp to be precisely what the normal sysenter /* Xen doesn't set %esp to be precisely what the normal sysenter
...@@ -1239,11 +1215,6 @@ return_to_handler: ...@@ -1239,11 +1215,6 @@ return_to_handler:
jmp *%ecx jmp *%ecx
#endif #endif
/*
* Some functions should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
#ifdef CONFIG_TRACING #ifdef CONFIG_TRACING
ENTRY(trace_page_fault) ENTRY(trace_page_fault)
RING0_EC_FRAME RING0_EC_FRAME
...@@ -1453,7 +1424,3 @@ ENTRY(async_page_fault) ...@@ -1453,7 +1424,3 @@ ENTRY(async_page_fault)
END(async_page_fault) END(async_page_fault)
#endif #endif
/*
* End of kprobes section
*/
.popsection
...@@ -487,8 +487,6 @@ ENDPROC(native_usergs_sysret64) ...@@ -487,8 +487,6 @@ ENDPROC(native_usergs_sysret64)
TRACE_IRQS_OFF TRACE_IRQS_OFF
.endm .endm
/* save complete stack frame */
.pushsection .kprobes.text, "ax"
ENTRY(save_paranoid) ENTRY(save_paranoid)
XCPT_FRAME 1 RDI+8 XCPT_FRAME 1 RDI+8
cld cld
...@@ -517,7 +515,6 @@ ENTRY(save_paranoid) ...@@ -517,7 +515,6 @@ ENTRY(save_paranoid)
1: ret 1: ret
CFI_ENDPROC CFI_ENDPROC
END(save_paranoid) END(save_paranoid)
.popsection
/* /*
* A newly forked process directly context switches into this address. * A newly forked process directly context switches into this address.
...@@ -975,10 +972,6 @@ END(interrupt) ...@@ -975,10 +972,6 @@ END(interrupt)
call \func call \func
.endm .endm
/*
* Interrupt entry/exit should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
/* /*
* The interrupt stubs push (~vector+0x80) onto the stack and * The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt. * then jump to common_interrupt.
...@@ -1113,10 +1106,6 @@ ENTRY(retint_kernel) ...@@ -1113,10 +1106,6 @@ ENTRY(retint_kernel)
CFI_ENDPROC CFI_ENDPROC
END(common_interrupt) END(common_interrupt)
/*
* End of kprobes section
*/
.popsection
/* /*
* APIC interrupts. * APIC interrupts.
...@@ -1477,11 +1466,6 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ ...@@ -1477,11 +1466,6 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
hyperv_callback_vector hyperv_vector_handler hyperv_callback_vector hyperv_vector_handler
#endif /* CONFIG_HYPERV */ #endif /* CONFIG_HYPERV */
/*
* Some functions should be protected against kprobes
*/
.pushsection .kprobes.text, "ax"
paranoidzeroentry_ist debug do_debug DEBUG_STACK paranoidzeroentry_ist debug do_debug DEBUG_STACK
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
paranoiderrorentry stack_segment do_stack_segment paranoiderrorentry stack_segment do_stack_segment
...@@ -1898,7 +1882,3 @@ ENTRY(ignore_sysret) ...@@ -1898,7 +1882,3 @@ ENTRY(ignore_sysret)
CFI_ENDPROC CFI_ENDPROC
END(ignore_sysret) END(ignore_sysret)
/*
* End of kprobes section
*/
.popsection
...@@ -1065,6 +1065,14 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -1065,6 +1065,14 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
return 0; return 0;
} }
bool arch_within_kprobe_blacklist(unsigned long addr)
{
return (addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end) ||
(addr >= (unsigned long)__entry_text_start &&
addr < (unsigned long)__entry_text_end);
}
int __init arch_init_kprobes(void) int __init arch_init_kprobes(void)
{ {
return 0; return 0;
......
...@@ -265,6 +265,7 @@ extern void arch_disarm_kprobe(struct kprobe *p); ...@@ -265,6 +265,7 @@ extern void arch_disarm_kprobe(struct kprobe *p);
extern int arch_init_kprobes(void); extern int arch_init_kprobes(void);
extern void show_registers(struct pt_regs *regs); extern void show_registers(struct pt_regs *regs);
extern void kprobes_inc_nmissed_count(struct kprobe *p); extern void kprobes_inc_nmissed_count(struct kprobe *p);
extern bool arch_within_kprobe_blacklist(unsigned long addr);
struct kprobe_insn_cache { struct kprobe_insn_cache {
struct mutex mutex; struct mutex mutex;
......
...@@ -96,9 +96,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash) ...@@ -96,9 +96,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
static struct kprobe_blackpoint kprobe_blacklist[] = { static struct kprobe_blackpoint kprobe_blacklist[] = {
{"preempt_schedule",}, {"preempt_schedule",},
{"native_get_debugreg",}, {"native_get_debugreg",},
{"irq_entries_start",},
{"common_interrupt",},
{"mcount",}, /* mcount can be called from everywhere */
{NULL} /* Terminator */ {NULL} /* Terminator */
}; };
...@@ -1324,12 +1321,18 @@ static int __kprobes register_aggr_kprobe(struct kprobe *orig_p, ...@@ -1324,12 +1321,18 @@ static int __kprobes register_aggr_kprobe(struct kprobe *orig_p,
return ret; return ret;
} }
bool __weak arch_within_kprobe_blacklist(unsigned long addr)
{
/* The __kprobes marked functions and entry code must not be probed */
return addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end;
}
static int __kprobes in_kprobes_functions(unsigned long addr) static int __kprobes in_kprobes_functions(unsigned long addr)
{ {
struct kprobe_blackpoint *kb; struct kprobe_blackpoint *kb;
if (addr >= (unsigned long)__kprobes_text_start && if (arch_within_kprobe_blacklist(addr))
addr < (unsigned long)__kprobes_text_end)
return -EINVAL; return -EINVAL;
/* /*
* If there exists a kprobe_blacklist, verify and * If there exists a kprobe_blacklist, verify and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment