kprobes/x86-32: Move irq-exit functions to kprobes section
Move irq-exit functions to .kprobes.text section to protect against kprobes recursion. When I ran kprobe stress test on x86-32, I found below symbols cause unrecoverable recursive probing: ret_from_exception ret_from_intr check_userspace restore_all restore_all_notrace restore_nocheck irq_return And also, I found some interrupt/exception entry points that cause similar problems. This patch moves those symbols (including their container functions) to .kprobes.text section to prevent any kprobes probing. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> LKML-Reference: <20090908164755.24050.81182.stgit@dhcp-100-2-132.bos.redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
This commit is contained in:
committed by
Frederic Weisbecker
parent
f12b4f546b
commit
a00e817f42
@@ -333,6 +333,10 @@ ENTRY(ret_from_fork)
|
|||||||
CFI_ENDPROC
|
CFI_ENDPROC
|
||||||
END(ret_from_fork)
|
END(ret_from_fork)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
@@ -383,6 +387,10 @@ 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. */
|
||||||
@@ -513,6 +521,10 @@ 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
|
||||||
@@ -705,6 +717,10 @@ syscall_badsys:
|
|||||||
jmp resume_userspace
|
jmp resume_userspace
|
||||||
END(syscall_badsys)
|
END(syscall_badsys)
|
||||||
CFI_ENDPROC
|
CFI_ENDPROC
|
||||||
|
/*
|
||||||
|
* End of kprobes section
|
||||||
|
*/
|
||||||
|
.popsection
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System calls that need a pt_regs pointer.
|
* System calls that need a pt_regs pointer.
|
||||||
@@ -814,6 +830,10 @@ 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; \
|
||||||
@@ -980,6 +1000,10 @@ 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
|
||||||
|
|
||||||
ENTRY(kernel_thread_helper)
|
ENTRY(kernel_thread_helper)
|
||||||
pushl $0 # fake return address for unwinder
|
pushl $0 # fake return address for unwinder
|
||||||
|
@@ -91,6 +91,8 @@ static 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",},
|
||||||
{NULL} /* Terminator */
|
{NULL} /* Terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user