From 098b080b3a50fd9db952ed96716ba2a3de88f91b Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Wed, 16 Dec 2015 18:03:39 +0300 Subject: [PATCH] [FIX] unexpected undefined instruction after disarm kprobe After disarm kprobe there is race condition in kernel within undefined instruction handler (between undefined instruction firing and seaching for hooks). Now kprobe register undef hook on all instruction and skip 'false exeption'. Change-Id: I972082ca5b94506e59306b9fe5834fccf883f83b Signed-off-by: Vyacheslav Cherkashin --- kprobe/arch/arm/swap-asm/swap_kprobes.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kprobe/arch/arm/swap-asm/swap_kprobes.c b/kprobe/arch/arm/swap-asm/swap_kprobes.c index b76aba5..32f3d69 100644 --- a/kprobe/arch/arm/swap-asm/swap_kprobes.c +++ b/kprobe/arch/arm/swap-asm/swap_kprobes.c @@ -460,7 +460,16 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) local_irq_save(flags); preempt_disable(); - ret = kprobe_handler(regs); + + if (likely(instr == BREAKPOINT_INSTRUCTION)) { + ret = kprobe_handler(regs); + } else { + struct kprobe *p = swap_get_kprobe((void *)regs->ARM_pc); + + /* skip false exeption */ + ret = p && (p->opcode == instr) ? 0 : 1; + } + swap_preempt_enable_no_resched(); local_irq_restore(flags); @@ -852,8 +861,8 @@ EXPORT_SYMBOL_GPL(swap_unregister_undef_hook); /* kernel probes hook */ static struct undef_hook undef_ho_k = { - .instr_mask = 0xffffffff, - .instr_val = BREAKPOINT_INSTRUCTION, + .instr_mask = 0, + .instr_val = 0, .cpsr_mask = MODE_MASK, .cpsr_val = SVC_MODE, .fn = kprobe_trap_handler -- 2.7.4