public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol
@ 2026-04-07 20:39 Andrey Grodzovsky
  2026-04-07 20:39 ` [PATCH bpf-next v7 1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes Andrey Grodzovsky
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Andrey Grodzovsky @ 2026-04-07 20:39 UTC (permalink / raw)
  To: bpf, linux-trace-kernel
  Cc: ast, daniel, andrii, jolsa, rostedt, mhiramat, ihor.solodrai,
	emil, linux-open-source

When a kernel module exports a symbol with the same name as an existing
vmlinux symbol, kprobe attachment fails with -EADDRNOTAVAIL because
number_of_same_symbols() counts matches across both vmlinux and all
loaded modules, returning a count greater than 1.

This series takes a different approach from v1-v4, which implemented a
libbpf-side fallback parsing /proc/kallsyms and retrying with the
absolute address. That approach was rejected (Andrii Nakryiko, Ihor
Solodrai) because ambiguous symbol resolution does not belong in libbpf.

Following Ihor's suggestion, this series fixes the root cause in the
kernel: when an unqualified symbol name is given and the symbol is found
in vmlinux, prefer the vmlinux symbol and do not scan loaded modules.
This makes the skeleton auto-attach path work transparently with no
libbpf changes needed.

Patch 1: Kernel fix - return vmlinux-only count from
         number_of_same_symbols() when the symbol is found in vmlinux,
         preventing module shadows from causing -EADDRNOTAVAIL.
Patch 2: Selftests using bpf_fentry_shadow_test which exists in both
         vmlinux and bpf_testmod - tests unqualified (vmlinux) and
         MOD:SYM (module) attachment across all four attach modes, plus
         kprobe_multi with the duplicate symbol.

Changes since v6 [1]:
  - Fix comment style: use /* on its own line instead of networking-style
    /* text on opener line (Alexei Starovoitov).

[1] https://lore.kernel.org/bpf/20260407165145.1651061-1-andrey.grodzovsky@crowdstrike.com/

Andrey Grodzovsky (2):
  tracing: Prefer vmlinux symbols over module symbols for unqualified
    kprobes
  selftests/bpf: Add tests for kprobe attachment with duplicate symbols

 kernel/trace/trace_kprobe.c                   |  8 +++
 .../selftests/bpf/prog_tests/attach_probe.c   | 69 +++++++++++++++++++
 .../bpf/prog_tests/kprobe_multi_test.c        | 40 +++++++++++
 3 files changed, 117 insertions(+)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH bpf-next v7 1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes
  2026-04-07 20:39 [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol Andrey Grodzovsky
@ 2026-04-07 20:39 ` Andrey Grodzovsky
  2026-04-07 20:39 ` [PATCH bpf-next v7 2/2] selftests/bpf: Add tests for kprobe attachment with duplicate symbols Andrey Grodzovsky
  2026-04-08  1:20 ` [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Andrey Grodzovsky @ 2026-04-07 20:39 UTC (permalink / raw)
  To: bpf, linux-trace-kernel
  Cc: ast, daniel, andrii, jolsa, rostedt, mhiramat, ihor.solodrai,
	emil, linux-open-source

When an unqualified kprobe target exists in both vmlinux and a loaded
module, number_of_same_symbols() returns a count greater than 1,
causing kprobe attachment to fail with -EADDRNOTAVAIL even though the
vmlinux symbol is unambiguous.

When no module qualifier is given and the symbol is found in vmlinux,
return the vmlinux-only count without scanning loaded modules. This
preserves the existing behavior for all other cases:
- Symbol only in a module: vmlinux count is 0, falls through to module
  scan as before.
- Symbol qualified with MOD:SYM: mod != NULL, unchanged path.
- Symbol ambiguous within vmlinux itself: count > 1 is returned as-is.

Fixes: 926fe783c8a6 ("tracing/kprobes: Fix symbol counting logic by looking at modules as well")
Fixes: 9d8616034f16 ("tracing/kprobes: Add symbol counting check when module loads")
Suggested-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
 kernel/trace/trace_kprobe.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index a5dbb72528e0..058724c41c46 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -765,6 +765,14 @@ static unsigned int number_of_same_symbols(const char *mod, const char *func_nam
 	if (!mod)
 		kallsyms_on_each_match_symbol(count_symbols, func_name, &ctx.count);
 
+	/*
+	 * If the symbol is found in vmlinux, use vmlinux resolution only.
+	 * This prevents module symbols from shadowing vmlinux symbols
+	 * and causing -EADDRNOTAVAIL for unqualified kprobe targets.
+	 */
+	if (!mod && ctx.count > 0)
+		return ctx.count;
+
 	module_kallsyms_on_each_symbol(mod, count_mod_symbols, &ctx);
 
 	return ctx.count;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH bpf-next v7 2/2] selftests/bpf: Add tests for kprobe attachment with duplicate symbols
  2026-04-07 20:39 [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol Andrey Grodzovsky
  2026-04-07 20:39 ` [PATCH bpf-next v7 1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes Andrey Grodzovsky
@ 2026-04-07 20:39 ` Andrey Grodzovsky
  2026-04-08  1:20 ` [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Andrey Grodzovsky @ 2026-04-07 20:39 UTC (permalink / raw)
  To: bpf, linux-trace-kernel
  Cc: ast, daniel, andrii, jolsa, rostedt, mhiramat, ihor.solodrai,
	emil, linux-open-source

bpf_fentry_shadow_test exists in both vmlinux (net/bpf/test_run.c) and
bpf_testmod (bpf_testmod.c), creating a duplicate symbol condition when
bpf_testmod is loaded. Add subtests that verify kprobe behavior with
this duplicate symbol:

In attach_probe:
- dup-sym-{default,legacy,perf,link}: unqualified attach succeeds
  across all four modes, preferring vmlinux over module shadow.
- MOD:SYM qualification attaches to the module version.

In kprobe_multi_test:
- dup_sym: kprobe_multi attach with kprobe and kretprobe succeeds.

bpf_fentry_shadow_test is not invoked via test_run, so tests verify
attach and detach succeed without triggering the probe.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
 .../selftests/bpf/prog_tests/attach_probe.c   | 69 +++++++++++++++++++
 .../bpf/prog_tests/kprobe_multi_test.c        | 40 +++++++++++
 2 files changed, 109 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
index 12a841afda68..e8c1a619e330 100644
--- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c
+++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
@@ -197,6 +197,66 @@ static void test_attach_kprobe_legacy_by_addr_reject(void)
 	test_attach_probe_manual__destroy(skel);
 }
 
+/*
+ * bpf_fentry_shadow_test exists in both vmlinux (net/bpf/test_run.c) and
+ * bpf_testmod (bpf_testmod.c). When bpf_testmod is loaded the symbol is
+ * duplicated. Test that kprobe attachment handles this correctly:
+ * - Unqualified name ("bpf_fentry_shadow_test") attaches to vmlinux.
+ * - MOD:SYM name ("bpf_testmod:bpf_fentry_shadow_test") attaches to module.
+ *
+ * Note: bpf_fentry_shadow_test is not invoked via test_run, so we only
+ * verify that attach and detach succeed without triggering the probe.
+ */
+static void test_attach_probe_dup_sym(enum probe_attach_mode attach_mode)
+{
+	DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, kprobe_opts);
+	struct bpf_link *kprobe_link, *kretprobe_link;
+	struct test_attach_probe_manual *skel;
+
+	skel = test_attach_probe_manual__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "skel_dup_sym_open_and_load"))
+		return;
+
+	kprobe_opts.attach_mode = attach_mode;
+
+	/* Unqualified: should attach to vmlinux symbol */
+	kprobe_opts.retprobe = false;
+	kprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kprobe,
+						      "bpf_fentry_shadow_test",
+						      &kprobe_opts);
+	if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe_vmlinux"))
+		goto cleanup;
+	bpf_link__destroy(kprobe_link);
+
+	kprobe_opts.retprobe = true;
+	kretprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kretprobe,
+							 "bpf_fentry_shadow_test",
+							 &kprobe_opts);
+	if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe_vmlinux"))
+		goto cleanup;
+	bpf_link__destroy(kretprobe_link);
+
+	/* MOD:SYM qualified: should attach to module symbol */
+	kprobe_opts.retprobe = false;
+	kprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kprobe,
+						      "bpf_testmod:bpf_fentry_shadow_test",
+						      &kprobe_opts);
+	if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe_module"))
+		goto cleanup;
+	bpf_link__destroy(kprobe_link);
+
+	kprobe_opts.retprobe = true;
+	kretprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kretprobe,
+							 "bpf_testmod:bpf_fentry_shadow_test",
+							 &kprobe_opts);
+	if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe_module"))
+		goto cleanup;
+	bpf_link__destroy(kretprobe_link);
+
+cleanup:
+	test_attach_probe_manual__destroy(skel);
+}
+
 /* attach uprobe/uretprobe long event name testings */
 static void test_attach_uprobe_long_event_name(void)
 {
@@ -559,6 +619,15 @@ void test_attach_probe(void)
 	if (test__start_subtest("kprobe-legacy-by-addr-reject"))
 		test_attach_kprobe_legacy_by_addr_reject();
 
+	if (test__start_subtest("dup-sym-default"))
+		test_attach_probe_dup_sym(PROBE_ATTACH_MODE_DEFAULT);
+	if (test__start_subtest("dup-sym-legacy"))
+		test_attach_probe_dup_sym(PROBE_ATTACH_MODE_LEGACY);
+	if (test__start_subtest("dup-sym-perf"))
+		test_attach_probe_dup_sym(PROBE_ATTACH_MODE_PERF);
+	if (test__start_subtest("dup-sym-link"))
+		test_attach_probe_dup_sym(PROBE_ATTACH_MODE_LINK);
+
 	if (test__start_subtest("auto"))
 		test_attach_probe_auto(skel);
 	if (test__start_subtest("kprobe-sleepable"))
diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
index 78c974d4ea33..20ddff6812e9 100644
--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
@@ -633,6 +633,44 @@ static void test_attach_write_ctx(void)
 }
 #endif
 
+/*
+ * Test kprobe_multi handles shadow symbols (vmlinux + module duplicate).
+ * bpf_fentry_shadow_test exists in both vmlinux and bpf_testmod.
+ * kprobe_multi resolves via ftrace_lookup_symbols() which finds the
+ * vmlinux symbol first and stops, so this should always succeed.
+ */
+static void test_attach_probe_dup_sym(void)
+{
+	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
+	const char *syms[1] = { "bpf_fentry_shadow_test" };
+	struct kprobe_multi *skel = NULL;
+	struct bpf_link *link1 = NULL, *link2 = NULL;
+
+	skel = kprobe_multi__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))
+		goto cleanup;
+
+	skel->bss->pid = getpid();
+	opts.syms = syms;
+	opts.cnt = ARRAY_SIZE(syms);
+
+	link1 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
+						      NULL, &opts);
+	if (!ASSERT_OK_PTR(link1, "attach_kprobe_multi_dup_sym"))
+		goto cleanup;
+
+	opts.retprobe = true;
+	link2 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kretprobe_manual,
+						      NULL, &opts);
+	if (!ASSERT_OK_PTR(link2, "attach_kretprobe_multi_dup_sym"))
+		goto cleanup;
+
+cleanup:
+	bpf_link__destroy(link2);
+	bpf_link__destroy(link1);
+	kprobe_multi__destroy(skel);
+}
+
 void serial_test_kprobe_multi_bench_attach(void)
 {
 	if (test__start_subtest("kernel"))
@@ -676,5 +714,7 @@ void test_kprobe_multi_test(void)
 		test_unique_match();
 	if (test__start_subtest("attach_write_ctx"))
 		test_attach_write_ctx();
+	if (test__start_subtest("dup_sym"))
+		test_attach_probe_dup_sym();
 	RUN_TESTS(kprobe_multi_verifier);
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol
  2026-04-07 20:39 [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol Andrey Grodzovsky
  2026-04-07 20:39 ` [PATCH bpf-next v7 1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes Andrey Grodzovsky
  2026-04-07 20:39 ` [PATCH bpf-next v7 2/2] selftests/bpf: Add tests for kprobe attachment with duplicate symbols Andrey Grodzovsky
@ 2026-04-08  1:20 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-04-08  1:20 UTC (permalink / raw)
  To: Andrey Grodzovsky
  Cc: bpf, linux-trace-kernel, ast, daniel, andrii, jolsa, rostedt,
	mhiramat, ihor.solodrai, emil, linux-open-source

Hello:

This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Tue, 7 Apr 2026 16:39:10 -0400 you wrote:
> When a kernel module exports a symbol with the same name as an existing
> vmlinux symbol, kprobe attachment fails with -EADDRNOTAVAIL because
> number_of_same_symbols() counts matches across both vmlinux and all
> loaded modules, returning a count greater than 1.
> 
> This series takes a different approach from v1-v4, which implemented a
> libbpf-side fallback parsing /proc/kallsyms and retrying with the
> absolute address. That approach was rejected (Andrii Nakryiko, Ihor
> Solodrai) because ambiguous symbol resolution does not belong in libbpf.
> 
> [...]

Here is the summary with links:
  - [bpf-next,v7,1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes
    https://git.kernel.org/bpf/bpf-next/c/1870ddcd94b0
  - [bpf-next,v7,2/2] selftests/bpf: Add tests for kprobe attachment with duplicate symbols
    https://git.kernel.org/bpf/bpf-next/c/cea4323f1cfe

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-08  1:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 20:39 [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol Andrey Grodzovsky
2026-04-07 20:39 ` [PATCH bpf-next v7 1/2] tracing: Prefer vmlinux symbols over module symbols for unqualified kprobes Andrey Grodzovsky
2026-04-07 20:39 ` [PATCH bpf-next v7 2/2] selftests/bpf: Add tests for kprobe attachment with duplicate symbols Andrey Grodzovsky
2026-04-08  1:20 ` [PATCH bpf-next v7 0/2] tracing: Fix kprobe attachment when module shadows vmlinux symbol patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox