From nobody Fri Oct 3 11:26:01 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A242313538; Tue, 2 Sep 2025 14:35:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756823737; cv=none; b=qNtTLb9ywZjmw9YVPZFzUrsPT0cmiYWpc5WtgcnHrar3pjU+p3nU4KijnfxMa59B2GCNGv3fHG0HA+nsyu+Z9Yt2ulMmYdbXopUnvcpQzMMdV35tSBDc/8xlfPn3P1HVGk1RRlyH8vIBvGV4YaOCnTBRSZ56F34GbkSML5zONI8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756823737; c=relaxed/simple; bh=UXYiSTNdvGRRIKwbtj+YYd94kdNwShC5KeHjHnOGO/o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fR5vxqXOVl+1wm8fW3wjB0ltQ11GBqfbYOV6j7j1UGialyDJCK3m3yDguEv2UuaX4+BpwJOnWxIGMcsOBv1AOkGL4IswIXBvkLnuaEtK3PUuVReKqyhLHGsoxY5Ssr5S2+7TQDFCYZJGMHZYQ5b7GFXFns6Tf8MKbQBT/qifLM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QO+ypgHn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QO+ypgHn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 83987C4CEED; Tue, 2 Sep 2025 14:35:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756823737; bh=UXYiSTNdvGRRIKwbtj+YYd94kdNwShC5KeHjHnOGO/o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QO+ypgHn86/YE53znM/cNDWDF7eXK0lZ/ce692MfM6qZADLXqnWh3b5vRXj6g3jTP Wppu5qAtadCXEcBaTpE4VoRjEJCn6osOdn4GKoKYmnZ5d8V72HtRPrs8KZl3Spk6nf uoxBqLuHeOdZIsJ/msv6eQT0MipuhX/93Btng2aD3x4+Pfp1uLhXeZ16ZVYAzkza1V rdBctkL9i+PKTubz8ER4KrIa4mKPOpkZrnNU5uq23Z6K8q+KGUopaokiqyz4pGjivd EqLl6d9zD8hXdCGRyXsjoYfO08rDkmFYtiIfoGPF0BZ6BNf8PGyjMVS/ujAidC8bbW edMlz5Z01Q/Aw== From: Jiri Olsa To: Oleg Nesterov , Masami Hiramatsu , Peter Zijlstra , Andrii Nakryiko Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, x86@kernel.org, Song Liu , Yonghong Song , John Fastabend , Hao Luo , Steven Rostedt , Ingo Molnar Subject: [PATCH perf/core 02/11] uprobes: Skip emulate/sstep on unique uprobe when ip is changed Date: Tue, 2 Sep 2025 16:34:55 +0200 Message-ID: <20250902143504.1224726-3-jolsa@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250902143504.1224726-1-jolsa@kernel.org> References: <20250902143504.1224726-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If uprobe consumer changes instruction pointer we still execute (single step or emulate) the original instruction and increment the ip register with the size of the instruction. In case the instruction is emulated, the new ip register value is incremented with the instructions size and process is likely to crash with illegal instruction. In case the instruction is single-stepped, the ip register change is lost and process continues with the original ip register value. If user decided to take execution elsewhere, it makes little sense to execute the original instruction, so let's skip it. Allowing this behaviour only for uprobe with unique consumer attached. Signed-off-by: Jiri Olsa --- kernel/events/uprobes.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index b9b088f7333a..da8291941c6b 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -2568,7 +2568,7 @@ static bool ignore_ret_handler(int rc) return rc =3D=3D UPROBE_HANDLER_REMOVE || rc =3D=3D UPROBE_HANDLER_IGNORE; } =20 -static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) +static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs, boo= l *is_unique) { struct uprobe_consumer *uc; bool has_consumers =3D false, remove =3D true; @@ -2582,6 +2582,9 @@ static void handler_chain(struct uprobe *uprobe, stru= ct pt_regs *regs) __u64 cookie =3D 0; int rc =3D 0; =20 + if (is_unique) + *is_unique |=3D uc->is_unique; + if (uc->handler) { rc =3D uc->handler(uc, regs, &cookie); WARN(rc < 0 || rc > 2, @@ -2735,6 +2738,7 @@ static void handle_swbp(struct pt_regs *regs) { struct uprobe *uprobe; unsigned long bp_vaddr; + bool is_unique =3D false; int is_swbp; =20 bp_vaddr =3D uprobe_get_swbp_addr(regs); @@ -2789,7 +2793,10 @@ static void handle_swbp(struct pt_regs *regs) if (arch_uprobe_ignore(&uprobe->arch, regs)) goto out; =20 - handler_chain(uprobe, regs); + handler_chain(uprobe, regs, &is_unique); + + if (is_unique && instruction_pointer(regs) !=3D bp_vaddr) + goto out; =20 /* Try to optimize after first hit. */ arch_uprobe_optimize(&uprobe->arch, bp_vaddr); @@ -2819,7 +2826,7 @@ void handle_syscall_uprobe(struct pt_regs *regs, unsi= gned long bp_vaddr) return; if (arch_uprobe_ignore(&uprobe->arch, regs)) return; - handler_chain(uprobe, regs); + handler_chain(uprobe, regs, NULL); } =20 /* --=20 2.51.0