From 2ac656c800f22de1799b34e8f8dfdacc9f9ff968 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:29:47 +0200 Subject: [PATCH] --- yaml --- r: 312213 b: refs/heads/master c: 56bb4cf6475d702d2fb00fc641aa6441097c0330 h: refs/heads/master i: 312211: 70faade7f254e2352528c2bf3da21a6bbe6eda4d v: v3 --- [refs] | 2 +- trunk/kernel/events/uprobes.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index f54442db9413..3c4b6284dac8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 77fc4af1b59d12ab3b1467adf0a5204806853123 +refs/heads/master: 56bb4cf6475d702d2fb00fc641aa6441097c0330 diff --git a/trunk/kernel/events/uprobes.c b/trunk/kernel/events/uprobes.c index a2ed82b4808c..1f02e3bbfc1d 100644 --- a/trunk/kernel/events/uprobes.c +++ b/trunk/kernel/events/uprobes.c @@ -1530,14 +1530,26 @@ static void handle_swbp(struct pt_regs *regs) struct uprobe_task *utask; struct uprobe *uprobe; unsigned long bp_vaddr; - int is_swbp; + int uninitialized_var(is_swbp); bp_vaddr = uprobe_get_swbp_addr(regs); uprobe = find_active_uprobe(bp_vaddr, &is_swbp); if (!uprobe) { - /* No matching uprobe; signal SIGTRAP. */ - send_sig(SIGTRAP, current, 0); + if (is_swbp > 0) { + /* No matching uprobe; signal SIGTRAP. */ + send_sig(SIGTRAP, current, 0); + } else { + /* + * Either we raced with uprobe_unregister() or we can't + * access this memory. The latter is only possible if + * another thread plays with our ->mm. In both cases + * we can simply restart. If this vma was unmapped we + * can pretend this insn was not executed yet and get + * the (correct) SIGSEGV after restart. + */ + instruction_pointer_set(regs, bp_vaddr); + } return; }