Messages in this thread Patch in this message | | | From | "Naveen N. Rao" <> | Subject | [PATCH v3 3/3] kernel/uprobes: Fix check for active uprobe | Date | Fri, 22 Sep 2017 14:43:38 +0530 |
| |
If we try to install a uprobe on a breakpoint instruction when the binary has not yet been mmap'ed, we register the probe but delay installing the breakpoint for when the binary is actually mmap'ed. On mmap, uprobe_mmap() calls prepare_uprobe() which then refuses to install the breakpoint. In this case however, when the breakpoint hits, we incorrectly assume that the probe hit and end up looping.
This happens because find_active_uprobe() does not check if we successfully installed the breakpoint or not. Fix this by checking if UPROBE_COPY_INSN is set in uprobe->flags in find_active_uprobe(). Since handle_swbp() calls find_active_uprobe(), we can remove the redundant check there.
Reported-by: Anton Blanchard <anton@samba.org> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> --- kernel/events/uprobes.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 8da6570b4467..4c5dc6fb2abf 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1751,6 +1751,19 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) uprobe = find_uprobe(inode, offset); } + /* Ensure that the breakpoint was actually installed */ + if (uprobe) { + /* + * TODO: move copy_insn/etc into _register and remove + * this hack. After we hit the bp, _unregister + + * _register can install the new and not-yet-analyzed + * uprobe at the same address, restart. + */ + smp_rmb(); /* pairs with wmb() in prepare_uprobe() */ + if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) + uprobe = NULL; + } + if (!uprobe) *is_swbp = is_trap_at_addr(mm, bp_vaddr); } else { @@ -1911,15 +1924,6 @@ static void handle_swbp(struct pt_regs *regs) /* change it in advance for ->handler() and restart */ instruction_pointer_set(regs, bp_vaddr); - /* - * TODO: move copy_insn/etc into _register and remove this hack. - * After we hit the bp, _unregister + _register can install the - * new and not-yet-analyzed uprobe at the same address, restart. - */ - smp_rmb(); /* pairs with wmb() in install_breakpoint() */ - if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) - goto out; - /* Tracing handlers use ->utask to communicate with fetch methods */ if (!get_utask()) goto out; -- 2.14.1
| |