OSDN Git Service

arch/sh: Check for kprobe trap number before trying to handle a kprobe trap for-linus-20190617
authorMichael Karcher <kernel@mkarcher.dialup.fu-berlin.de>
Wed, 12 Jun 2019 13:08:37 +0000 (15:08 +0200)
committerYoshinori Sato <ysato@users.sourceforge.jp>
Wed, 26 Jun 2019 10:11:13 +0000 (19:11 +0900)
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>
arch/sh/kernel/kprobes.c

index 1f8c0d3..318296f 100644 (file)
@@ -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;