lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 22 Sep 2017 14:43:38 +0530
From:   "Naveen N. Rao" <naveen.n.rao@...ux.vnet.ibm.com>
To:     Ingo Molnar <mingo@...nel.org>
Cc:     Oleg Nesterov <oleg@...hat.com>,
        Srikar Dronamraju <srikar@...ux.vnet.ibm.com>,
        Ananth N Mavinakayanahalli <ananth@...ux.vnet.ibm.com>,
        Anton Blanchard <anton@...ba.org>,
        Michael Ellerman <mpe@...erman.id.au>,
        linux-kernel@...r.kernel.org
Subject: [PATCH v3 3/3] kernel/uprobes: Fix check for active uprobe

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@...ba.org>
Signed-off-by: Naveen N. Rao <naveen.n.rao@...ux.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ