summaryrefslogtreecommitdiff
path: root/arch/sh
diff options
context:
space:
mode:
authorMichael Karcher <kernel@mkarcher.dialup.fu-berlin.de>2019-06-12 15:08:37 +0200
committerYoshinori Sato <ysato@users.sourceforge.jp>2019-06-26 19:11:13 +0900
commitd3023897b4370bbf7f289806667a2380576d13dd (patch)
tree33224cefb6689fd0b1317c1adf34763cf9dff903 /arch/sh
parent7c04efc8d2efa6476cc4fc1228c1e20bdc4129ad (diff)
downloadlwn-d3023897b4370bbf7f289806667a2380576d13dd.tar.gz
lwn-d3023897b4370bbf7f289806667a2380576d13dd.zip
arch/sh: Check for kprobe trap number before trying to handle a kprobe trap
The DIE_TRAP notifier chain is run both for kprobe traps and for BUG/WARN traps. The kprobe code assumes to be only called for BREAKPOINT_INSTRUCTION, and concludes to have hit a concurrently removed kprobe if it finds anything else at the faulting locations. This includes TRAPA_BUG_OPCODE used for BUG and WARN. The consequence is that kprobe_handler returns 1. This makes kprobe_exceptions_notify return NOTIFY_STOP, and prevents handling the BUG statement. This also prevents moving $pc away from the trap instruction, so the system locks up in an endless loop Signed-off-by: Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/kprobes.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index 1f8c0d30567f..318296f48f1a 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -485,7 +485,8 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
addr = (kprobe_opcode_t *) (args->regs->pc);
- if (val == DIE_TRAP) {
+ if (val == DIE_TRAP &&
+ args->trapnr == (BREAKPOINT_INSTRUCTION & 0xff)) {
if (!kprobe_running()) {
if (kprobe_handler(args->regs)) {
ret = NOTIFY_STOP;