public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN
@ 2026-02-23 19:07 Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 01/20] selftests/bpf: Add simple strscpy() implementation Ihor Solodrai
                   ` (18 more replies)
  0 siblings, 19 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

This series includes various fixes aiming to enable test_progs run
with userspace address sanitizer on BPF CI.

The first five patches add a simplified implementation of strscpy() to
selftests/bpf and then replace strcpy/strncpy usages across the tests
with it. See relevant discussions [1][2].

Patch #6 fixes the selftests/bpf/test_progs build with:

    SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"

The subsequent patches fix bugs reported by the address sanitizer on
attempt to run the tests.

[1] https://lore.kernel.org/bpf/CAADnVQ+9uw2_o388j43EWiAPdMB=3FLx2jq-9zRSvqrv-wgRag@mail.gmail.com/
[2] https://lore.kernel.org/bpf/20260220182011.802116-1-ihor.solodrai@linux.dev/

---

v3->v4:
  - combine strscpy and ASAN series into one (Alexei)
  - make the count arg of strscpy() optional via macro and fixup
    relevant call sites (Alexei)
  - remove strscpy_cat() from this series (Alexei)

v3: https://lore.kernel.org/bpf/20260220222604.1155148-1-ihor.solodrai@linux.dev/

v2->v3:
  - rebase on top of "selftests/bpf: Add and use strscpy()"
    - https://lore.kernel.org/bpf/20260220182011.802116-1-ihor.solodrai@linux.dev/
  - uprobe_multi_test.c: memset static struct child at the beginning
    of a test *and* zero out child->thread in release_child (patch #9,
    Mykyta)
  - nits in test_sysctl.c (patch #11, Eduard)
  - bpftool_helpers.c: update to use strscpy (patch #14, Alexei)
  - add __asan_on_error handler to still dump test logs even with ASAN
    build (patch #15, Mykyta)

v2: https://lore.kernel.org/bpf/20260218003041.1156774-1-ihor.solodrai@linux.dev/

v1->v2:
  - rebase on bpf (v1 was targeting bpf-next)
  - add ASAN flag handling in selftests/bpf/Makefile (Eduard)
  - don't override SIGSEGV handler in test_progs with ASAN (Eduard)
  - add error messages in detect_bpftool_path (Mykyta)
  - various nits (Eduard, Jiri, Mykyta, Alexis)

v1: https://lore.kernel.org/bpf/20260212011356.3266753-1-ihor.solodrai@linux.dev/

---

Ihor Solodrai (20):
  selftests/bpf: Add simple strscpy() implementation
  selftests/bpf: Replace strcpy() calls with strscpy()
  selftests/bpf: Replace strncpy() with strscpy()
  selftests/bpf: Use strscpy in bpftool_helpers.c
  selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies
  selftests/bpf: Pass through build flags to bpftool and resolve_btfids
  resolve_btfids: Fix memory leaks reported by ASAN
  selftests/bpf: Add DENYLIST.asan
  selftests/bpf: Refactor bpf_get_ksyms() trace helper
  selftests/bpf: Fix memory leaks in tests
  selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
  veristat: Fix a memory leak for preset ENUMERATOR
  selftests/bpf: Fix use-after-free in xdp_metadata test
  selftests/bpf: Fix double thread join in uprobe_multi_test
  selftests/bpf: Fix resource leaks caused by missing cleanups
  selftests/bpf: Free bpf_object in test_sysctl
  selftests/bpf: Fix array bounds warning in jit_disasm_helpers
  selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
  selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
  selftests/bpf: Don't override SIGSEGV handler with ASAN

 tools/bpf/resolve_btfids/Makefile             |  7 +-
 tools/bpf/resolve_btfids/main.c               | 81 ++++++++++++-------
 tools/include/linux/args.h                    |  4 +
 tools/testing/selftests/bpf/DENYLIST.asan     |  3 +
 tools/testing/selftests/bpf/Makefile          | 13 ++-
 .../selftests/bpf/benchs/bench_trigger.c      | 14 ++--
 tools/testing/selftests/bpf/bpf_util.h        | 45 ++++++++---
 tools/testing/selftests/bpf/bpftool_helpers.c | 25 ++++--
 tools/testing/selftests/bpf/cgroup_helpers.c  |  2 +-
 .../selftests/bpf/jit_disasm_helpers.c        | 18 ++---
 tools/testing/selftests/bpf/network_helpers.c |  5 +-
 .../testing/selftests/bpf/prog_tests/align.c  |  2 +-
 .../selftests/bpf/prog_tests/bpf_iter.c       |  3 +-
 .../selftests/bpf/prog_tests/bpf_tcp_ca.c     |  2 +-
 .../bpf/prog_tests/cgrp_local_storage.c       |  4 +-
 .../selftests/bpf/prog_tests/ctx_rewrite.c    |  6 +-
 .../testing/selftests/bpf/prog_tests/dynptr.c |  5 +-
 .../selftests/bpf/prog_tests/fd_array.c       |  4 +-
 .../selftests/bpf/prog_tests/flow_dissector.c |  4 +-
 .../selftests/bpf/prog_tests/htab_update.c    |  1 +
 .../bpf/prog_tests/kmem_cache_iter.c          |  7 +-
 .../bpf/prog_tests/kprobe_multi_test.c        | 12 ++-
 .../selftests/bpf/prog_tests/lwt_seg6local.c  |  2 +-
 .../bpf/prog_tests/queue_stack_map.c          |  4 +-
 .../selftests/bpf/prog_tests/setget_sockopt.c |  2 +-
 .../bpf/prog_tests/skc_to_unix_sock.c         |  2 +-
 .../selftests/bpf/prog_tests/sockmap_basic.c  | 28 +++----
 .../selftests/bpf/prog_tests/sockmap_listen.c |  2 +-
 .../selftests/bpf/prog_tests/sockopt_sk.c     |  2 +-
 .../bpf/prog_tests/struct_ops_private_stack.c |  4 +-
 .../bpf/prog_tests/task_local_data.h          |  2 +-
 .../selftests/bpf/prog_tests/tc_opts.c        |  6 +-
 .../selftests/bpf/prog_tests/tc_redirect.c    |  2 +-
 .../selftests/bpf/prog_tests/test_sysctl.c    |  3 +
 .../selftests/bpf/prog_tests/test_tc_tunnel.c |  5 +-
 .../selftests/bpf/prog_tests/test_veristat.c  |  4 +-
 .../selftests/bpf/prog_tests/test_xsk.c       | 24 +++++-
 .../bpf/prog_tests/uprobe_multi_test.c        |  6 +-
 .../selftests/bpf/prog_tests/verifier_log.c   |  2 +-
 .../selftests/bpf/prog_tests/xdp_metadata.c   |  4 +-
 tools/testing/selftests/bpf/test_progs.c      | 38 ++++++---
 tools/testing/selftests/bpf/test_verifier.c   |  2 +-
 tools/testing/selftests/bpf/testing_helpers.c |  1 +
 tools/testing/selftests/bpf/trace_helpers.c   | 23 +++---
 tools/testing/selftests/bpf/trace_helpers.h   | 11 ++-
 tools/testing/selftests/bpf/veristat.c        |  2 +
 tools/testing/selftests/bpf/xdp_features.c    |  3 +-
 tools/testing/selftests/bpf/xdp_hw_metadata.c |  4 +-
 48 files changed, 291 insertions(+), 164 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/DENYLIST.asan

-- 
2.53.0


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

* [PATCH bpf v4 01/20] selftests/bpf: Add simple strscpy() implementation
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 02/20] selftests/bpf: Replace strcpy() calls with strscpy() Ihor Solodrai
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Replace bpf_strlcpy() in bpf_util.h with a sized_strscpy(), which is a
simplified sized_strscpy() from the kernel (lib/string.c [1]). It:
  * takes a count (destination size) parameter
  * guarantees NULL-termination
  * returns the number of characters copied or -E2BIG

Re-define strscpy macro similar to in-kernel implementation [2]: allow
the count parameter to be optional.

Add #ifdef-s to tools/include/linux/args.h, as they may be defined in
other system headers (for example, __CONCAT in sys/cdefs.h).

Fixup the single existing bpf_strlcpy() call in cgroup_helpers.c

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/string.c?h=v6.19#n113
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/string.h?h=v6.19#n91

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/include/linux/args.h                   |  4 ++
 tools/testing/selftests/bpf/bpf_util.h       | 45 ++++++++++++++------
 tools/testing/selftests/bpf/cgroup_helpers.c |  2 +-
 3 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/tools/include/linux/args.h b/tools/include/linux/args.h
index 2e8e65d975c7..14b268f2389a 100644
--- a/tools/include/linux/args.h
+++ b/tools/include/linux/args.h
@@ -22,7 +22,11 @@
 #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
 
 /* Concatenate two parameters, but allow them to be expanded beforehand. */
+#ifndef __CONCAT
 #define __CONCAT(a, b) a ## b
+#endif
+#ifndef CONCATENATE
 #define CONCATENATE(a, b) __CONCAT(a, b)
+#endif
 
 #endif	/* _LINUX_ARGS_H */
diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h
index 4bc2d25f33e1..6cb56501a505 100644
--- a/tools/testing/selftests/bpf/bpf_util.h
+++ b/tools/testing/selftests/bpf/bpf_util.h
@@ -8,6 +8,7 @@
 #include <errno.h>
 #include <syscall.h>
 #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */
+#include <linux/args.h>
 
 static inline unsigned int bpf_num_possible_cpus(void)
 {
@@ -21,25 +22,43 @@ static inline unsigned int bpf_num_possible_cpus(void)
 	return possible_cpus;
 }
 
-/* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst
- * is zero-terminated string no matter what (unless sz == 0, in which case
- * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs
- * in what is returned. Given this is internal helper, it's trivial to extend
- * this, when necessary. Use this instead of strncpy inside libbpf source code.
+/*
+ * Simplified strscpy() implementation. The kernel one is in lib/string.c
  */
-static inline void bpf_strlcpy(char *dst, const char *src, size_t sz)
+static inline ssize_t sized_strscpy(char *dest, const char *src, size_t count)
 {
-	size_t i;
+	long res = 0;
 
-	if (sz == 0)
-		return;
+	if (count == 0)
+		return -E2BIG;
 
-	sz--;
-	for (i = 0; i < sz && src[i]; i++)
-		dst[i] = src[i];
-	dst[i] = '\0';
+	while (count > 1) {
+		char c;
+
+		c = src[res];
+		dest[res] = c;
+		if (!c)
+			return res;
+		res++;
+		count--;
+	}
+
+	/* Force NUL-termination. */
+	dest[res] = '\0';
+
+	/* Return E2BIG if the source didn't stop */
+	return src[res] ? -E2BIG : res;
 }
 
+#define __strscpy0(dst, src, ...)	\
+	sized_strscpy(dst, src, sizeof(dst))
+#define __strscpy1(dst, src, size)	\
+	sized_strscpy(dst, src, size)
+
+#undef strscpy /* Redefine the placeholder from tools/include/linux/string.h */
+#define strscpy(dst, src, ...)	\
+	CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__)
+
 #define __bpf_percpu_val_align	__attribute__((__aligned__(8)))
 
 #define BPF_DECLARE_PERCPU(type, name)				\
diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c
index 20cede4db3ce..45cd0b479fe3 100644
--- a/tools/testing/selftests/bpf/cgroup_helpers.c
+++ b/tools/testing/selftests/bpf/cgroup_helpers.c
@@ -86,7 +86,7 @@ static int __enable_controllers(const char *cgroup_path, const char *controllers
 		enable[len] = 0;
 		close(fd);
 	} else {
-		bpf_strlcpy(enable, controllers, sizeof(enable));
+		strscpy(enable, controllers);
 	}
 
 	snprintf(path, sizeof(path), "%s/cgroup.subtree_control", cgroup_path);
-- 
2.53.0


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

* [PATCH bpf v4 02/20] selftests/bpf: Replace strcpy() calls with strscpy()
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 01/20] selftests/bpf: Add simple strscpy() implementation Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() " Ihor Solodrai
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

strcpy() does not perform bounds checking and is considered deprecated
[1]. Replace strcpy() calls with strscpy() defined in bpf_util.h.

[1] https://docs.kernel.org/process/deprecated.html#strcpy

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/network_helpers.c           | 2 +-
 tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c     | 2 +-
 tools/testing/selftests/bpf/prog_tests/setget_sockopt.c | 2 +-
 tools/testing/selftests/bpf/prog_tests/sockopt_sk.c     | 2 +-
 tools/testing/selftests/bpf/prog_tests/test_veristat.c  | 4 ++--
 tools/testing/selftests/bpf/xdp_features.c              | 3 ++-
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c
index 0a6a5561bed3..5374b7e16d53 100644
--- a/tools/testing/selftests/bpf/network_helpers.c
+++ b/tools/testing/selftests/bpf/network_helpers.c
@@ -432,7 +432,7 @@ int make_sockaddr(int family, const char *addr_str, __u16 port,
 		memset(addr, 0, sizeof(*sun));
 		sun->sun_family = family;
 		sun->sun_path[0] = 0;
-		strcpy(sun->sun_path + 1, addr_str);
+		strscpy(sun->sun_path + 1, addr_str, sizeof(sun->sun_path) - 1);
 		if (len)
 			*len = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(addr_str);
 		return 0;
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
index b7d1b52309d0..f829b6f09bc9 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
@@ -281,7 +281,7 @@ static void test_dctcp_fallback(void)
 	dctcp_skel = bpf_dctcp__open();
 	if (!ASSERT_OK_PTR(dctcp_skel, "dctcp_skel"))
 		return;
-	strcpy(dctcp_skel->rodata->fallback_cc, "cubic");
+	strscpy(dctcp_skel->rodata->fallback_cc, "cubic");
 	if (!ASSERT_OK(bpf_dctcp__load(dctcp_skel), "bpf_dctcp__load"))
 		goto done;
 
diff --git a/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c b/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c
index e4dac529d424..77fe1bfb7504 100644
--- a/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c
+++ b/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c
@@ -212,7 +212,7 @@ void test_setget_sockopt(void)
 	if (!ASSERT_OK_PTR(skel, "open skel"))
 		goto done;
 
-	strcpy(skel->rodata->veth, "binddevtest1");
+	strscpy(skel->rodata->veth, "binddevtest1");
 	skel->rodata->veth_ifindex = if_nametoindex("binddevtest1");
 	if (!ASSERT_GT(skel->rodata->veth_ifindex, 0, "if_nametoindex"))
 		goto done;
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
index ba6b3ec1156a..53637431ec5d 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
@@ -142,7 +142,7 @@ static int getsetsockopt(void)
 
 	/* TCP_CONGESTION can extend the string */
 
-	strcpy(buf.cc, "nv");
+	strscpy(buf.cc, "nv");
 	err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv"));
 	if (err) {
 		log_err("Failed to call setsockopt(TCP_CONGESTION)");
diff --git a/tools/testing/selftests/bpf/prog_tests/test_veristat.c b/tools/testing/selftests/bpf/prog_tests/test_veristat.c
index b38c16b4247f..9aff08ac55c0 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_veristat.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_veristat.c
@@ -24,9 +24,9 @@ static struct fixture *init_fixture(void)
 
 	/* for no_alu32 and cpuv4 veristat is in parent folder */
 	if (access("./veristat", F_OK) == 0)
-		strcpy(fix->veristat, "./veristat");
+		strscpy(fix->veristat, "./veristat");
 	else if (access("../veristat", F_OK) == 0)
-		strcpy(fix->veristat, "../veristat");
+		strscpy(fix->veristat, "../veristat");
 	else
 		PRINT_FAIL("Can't find veristat binary");
 
diff --git a/tools/testing/selftests/bpf/xdp_features.c b/tools/testing/selftests/bpf/xdp_features.c
index 595c79141cf3..a27ed663967c 100644
--- a/tools/testing/selftests/bpf/xdp_features.c
+++ b/tools/testing/selftests/bpf/xdp_features.c
@@ -16,6 +16,7 @@
 
 #include <network_helpers.h>
 
+#include "bpf_util.h"
 #include "xdp_features.skel.h"
 #include "xdp_features.h"
 
@@ -212,7 +213,7 @@ static void set_env_default(void)
 	env.feature.drv_feature = NETDEV_XDP_ACT_NDO_XMIT;
 	env.feature.action = -EINVAL;
 	env.ifindex = -ENODEV;
-	strcpy(env.ifname, "unknown");
+	strscpy(env.ifname, "unknown");
 	make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_CTRL_PORT,
 		      &env.dut_ctrl_addr, NULL);
 	make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_ECHO_PORT,
-- 
2.53.0


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

* [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() with strscpy()
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 01/20] selftests/bpf: Add simple strscpy() implementation Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 02/20] selftests/bpf: Replace strcpy() calls with strscpy() Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 22:28   ` Eduard Zingerman
  2026-02-23 19:07 ` [PATCH bpf v4 04/20] selftests/bpf: Use strscpy in bpftool_helpers.c Ihor Solodrai
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

strncpy() does not guarantee NULL-termination and is considered
deprecated [1]. Replace strncpy() calls with strscpy().

[1] https://docs.kernel.org/process/deprecated.html#strncpy-on-nul-terminated-strings

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/network_helpers.c             | 3 +--
 tools/testing/selftests/bpf/prog_tests/align.c            | 2 +-
 tools/testing/selftests/bpf/prog_tests/bpf_iter.c         | 3 +--
 tools/testing/selftests/bpf/prog_tests/flow_dissector.c   | 4 ++--
 tools/testing/selftests/bpf/prog_tests/queue_stack_map.c  | 4 ++--
 tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c | 2 +-
 tools/testing/selftests/bpf/prog_tests/task_local_data.h  | 2 +-
 tools/testing/selftests/bpf/prog_tests/tc_redirect.c      | 2 +-
 tools/testing/selftests/bpf/test_progs.c                  | 2 +-
 tools/testing/selftests/bpf/xdp_hw_metadata.c             | 4 ++--
 10 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c
index 5374b7e16d53..b82f572641b7 100644
--- a/tools/testing/selftests/bpf/network_helpers.c
+++ b/tools/testing/selftests/bpf/network_helpers.c
@@ -581,8 +581,7 @@ int open_tuntap(const char *dev_name, bool need_mac)
 		return -1;
 
 	ifr.ifr_flags = IFF_NO_PI | (need_mac ? IFF_TAP : IFF_TUN);
-	strncpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1);
-	ifr.ifr_name[IFNAMSIZ - 1] = '\0';
+	strscpy(ifr.ifr_name, dev_name);
 
 	err = ioctl(fd, TUNSETIFF, &ifr);
 	if (!ASSERT_OK(err, "ioctl(TUNSETIFF)")) {
diff --git a/tools/testing/selftests/bpf/prog_tests/align.c b/tools/testing/selftests/bpf/prog_tests/align.c
index 24c509ce4e5b..841a166b8081 100644
--- a/tools/testing/selftests/bpf/prog_tests/align.c
+++ b/tools/testing/selftests/bpf/prog_tests/align.c
@@ -633,7 +633,7 @@ static int do_test_single(struct bpf_align_test *test)
 	} else {
 		ret = 0;
 		/* We make a local copy so that we can strtok() it */
-		strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
+		strscpy(bpf_vlog_copy, bpf_vlog);
 		start = strstr(bpf_vlog_copy, main_pass_start);
 		if (!start) {
 			ret = 1;
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c
index 5225d69bf79b..c69080ca14f5 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c
@@ -346,8 +346,7 @@ static void test_task_sleepable(void)
 		close(finish_pipe[1]);
 
 		test_data = malloc(sizeof(char) * 10);
-		strncpy(test_data, "test_data", 10);
-		test_data[9] = '\0';
+		strscpy(test_data, "test_data", 10);
 
 		test_data_long = malloc(sizeof(char) * 5000);
 		for (int i = 0; i < 5000; ++i) {
diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
index 08bae13248c4..fb4892681464 100644
--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
@@ -570,7 +570,7 @@ static int create_tap(const char *ifname)
 	};
 	int fd, ret;
 
-	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	strscpy(ifr.ifr_name, ifname);
 
 	fd = open("/dev/net/tun", O_RDWR);
 	if (fd < 0)
@@ -599,7 +599,7 @@ static int ifup(const char *ifname)
 	struct ifreq ifr = {};
 	int sk, ret;
 
-	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	strscpy(ifr.ifr_name, ifname);
 
 	sk = socket(PF_INET, SOCK_DGRAM, 0);
 	if (sk < 0)
diff --git a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
index a043af9cd6d9..41441325e179 100644
--- a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
+++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
@@ -28,9 +28,9 @@ static void test_queue_stack_map_by_type(int type)
 		vals[i] = rand();
 
 	if (type == QUEUE)
-		strncpy(file, "./test_queue_map.bpf.o", sizeof(file));
+		strscpy(file, "./test_queue_map.bpf.o");
 	else if (type == STACK)
-		strncpy(file, "./test_stack_map.bpf.o", sizeof(file));
+		strscpy(file, "./test_stack_map.bpf.o");
 	else
 		return;
 
diff --git a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c
index 3eefdfed1db9..657d897958b6 100644
--- a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c
+++ b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c
@@ -34,7 +34,7 @@ void test_skc_to_unix_sock(void)
 
 	memset(&sockaddr, 0, sizeof(sockaddr));
 	sockaddr.sun_family = AF_UNIX;
-	strncpy(sockaddr.sun_path, sock_path, strlen(sock_path));
+	strscpy(sockaddr.sun_path, sock_path);
 	sockaddr.sun_path[0] = '\0';
 
 	err = bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
index 0f86b9275cf9..8342e2fe5260 100644
--- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
+++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
@@ -262,7 +262,7 @@ static tld_key_t __tld_create_key(const char *name, size_t size, bool dyn_data)
 		if (!atomic_compare_exchange_strong(&tld_meta_p->cnt, &cnt, cnt + 1))
 			goto retry;
 
-		strncpy(tld_meta_p->metadata[i].name, name, TLD_NAME_LEN);
+		strscpy(tld_meta_p->metadata[i].name, name);
 		atomic_store(&tld_meta_p->metadata[i].size, size);
 		return (tld_key_t){(__s16)off};
 	}
diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
index 76d72a59365e..64fbda082309 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
@@ -1095,7 +1095,7 @@ static int tun_open(char *name)
 
 	ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
 	if (*name)
-		strncpy(ifr.ifr_name, name, IFNAMSIZ);
+		strscpy(ifr.ifr_name, name);
 
 	err = ioctl(fd, TUNSETIFF, &ifr);
 	if (!ASSERT_OK(err, "ioctl TUNSETIFF"))
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 02a85dda30e6..d1418ec1f351 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1799,7 +1799,7 @@ static int worker_main_send_subtests(int sock, struct test_state *state)
 
 		msg.subtest_done.num = i;
 
-		strncpy(msg.subtest_done.name, subtest_state->name, MAX_SUBTEST_NAME);
+		strscpy(msg.subtest_done.name, subtest_state->name, MAX_SUBTEST_NAME);
 
 		msg.subtest_done.error_cnt = subtest_state->error_cnt;
 		msg.subtest_done.skipped = subtest_state->skipped;
diff --git a/tools/testing/selftests/bpf/xdp_hw_metadata.c b/tools/testing/selftests/bpf/xdp_hw_metadata.c
index 3d8de0d4c96a..6db3b5555a22 100644
--- a/tools/testing/selftests/bpf/xdp_hw_metadata.c
+++ b/tools/testing/selftests/bpf/xdp_hw_metadata.c
@@ -550,7 +550,7 @@ static int rxq_num(const char *ifname)
 	struct ifreq ifr = {
 		.ifr_data = (void *)&ch,
 	};
-	strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1);
+	strscpy(ifr.ifr_name, ifname);
 	int fd, ret;
 
 	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
@@ -571,7 +571,7 @@ static void hwtstamp_ioctl(int op, const char *ifname, struct hwtstamp_config *c
 	struct ifreq ifr = {
 		.ifr_data = (void *)cfg,
 	};
-	strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1);
+	strscpy(ifr.ifr_name, ifname);
 	int fd, ret;
 
 	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
-- 
2.53.0


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

* [PATCH bpf v4 04/20] selftests/bpf: Use strscpy in bpftool_helpers.c
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (2 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() " Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 05/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies Ihor Solodrai
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Replace strncpy() calls in bpftool_helpers.c with strscpy().

Pass the destination buffer size to detect_bpftool_path() instead of
hardcoding BPFTOOL_PATH_MAX_LEN.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/bpftool_helpers.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/bpf/bpftool_helpers.c b/tools/testing/selftests/bpf/bpftool_helpers.c
index a5824945a4a5..595a636fa13b 100644
--- a/tools/testing/selftests/bpf/bpftool_helpers.c
+++ b/tools/testing/selftests/bpf/bpftool_helpers.c
@@ -1,15 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0-only
-#include "bpftool_helpers.h"
 #include <unistd.h>
 #include <string.h>
 #include <stdbool.h>
 
+#include "bpf_util.h"
+#include "bpftool_helpers.h"
+
 #define BPFTOOL_PATH_MAX_LEN		64
 #define BPFTOOL_FULL_CMD_MAX_LEN	512
 
 #define BPFTOOL_DEFAULT_PATH		"tools/sbin/bpftool"
 
-static int detect_bpftool_path(char *buffer)
+static int detect_bpftool_path(char *buffer, size_t size)
 {
 	char tmp[BPFTOOL_PATH_MAX_LEN];
 
@@ -18,7 +20,7 @@ static int detect_bpftool_path(char *buffer)
 	 */
 	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "./%s", BPFTOOL_DEFAULT_PATH);
 	if (access(tmp, X_OK) == 0) {
-		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
+		strscpy(buffer, tmp, size);
 		return 0;
 	}
 
@@ -27,7 +29,7 @@ static int detect_bpftool_path(char *buffer)
 	 */
 	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "../%s", BPFTOOL_DEFAULT_PATH);
 	if (access(tmp, X_OK) == 0) {
-		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
+		strscpy(buffer, tmp, size);
 		return 0;
 	}
 
@@ -44,7 +46,7 @@ static int run_command(char *args, char *output_buf, size_t output_max_len)
 	int ret;
 
 	/* Detect and cache bpftool binary location */
-	if (bpftool_path[0] == 0 && detect_bpftool_path(bpftool_path))
+	if (bpftool_path[0] == 0 && detect_bpftool_path(bpftool_path, sizeof(bpftool_path)))
 		return 1;
 
 	ret = snprintf(command, BPFTOOL_FULL_CMD_MAX_LEN, "%s %s%s",
-- 
2.53.0


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

* [PATCH bpf v4 05/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (3 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 04/20] selftests/bpf: Use strscpy in bpftool_helpers.c Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 06/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Replace strncpy() with memcpy() in cases where the source is
non-NULL-terminated and the copy length is known.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c | 6 ++++--
 tools/testing/selftests/bpf/test_verifier.c          | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c b/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c
index dd75ccb03770..469e92869523 100644
--- a/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c
+++ b/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c
@@ -308,8 +308,10 @@ static int find_field_offset(struct btf *btf, char *pattern, regmatch_t *matches
 		return -1;
 	}
 
-	strncpy(type_str, type, type_sz);
-	strncpy(field_str, field, field_sz);
+	memcpy(type_str, type, type_sz);
+	type_str[type_sz] = '\0';
+	memcpy(field_str, field, field_sz);
+	field_str[field_sz] = '\0';
 	btf_id = btf__find_by_name(btf, type_str);
 	if (btf_id < 0) {
 		PRINT_FAIL("No BTF info for type %s\n", type_str);
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 27db34ecf3f5..a8ae03c57bba 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -1320,7 +1320,7 @@ static bool cmp_str_seq(const char *log, const char *exp)
 			printf("FAIL\nTestcase bug\n");
 			return false;
 		}
-		strncpy(needle, exp, len);
+		memcpy(needle, exp, len);
 		needle[len] = 0;
 		q = strstr(log, needle);
 		if (!q) {
-- 
2.53.0


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

* [PATCH bpf v4 06/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (4 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 05/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 07/20] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

EXTRA_* and SAN_* build flags were not correctly propagated to bpftool
and resolve_btids when building selftests/bpf. This led to various
build errors on attempt to build with SAN_CFLAGS="-fsanitize=address",
for example.

Fix the makefiles to address this:
  - Pass SAN_CFLAGS/SAN_LDFLAGS to bpftool and resolve_btfids build
  - Propagate EXTRA_LDFLAGS to resolve_btfids link command
  - Use pkg-config to detect zlib and zstd for resolve_btfids, similar
    libelf handling

Also check for ASAN flag in selftests/bpf/Makefile for convenience.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/resolve_btfids/Makefile    |  7 +++++--
 tools/testing/selftests/bpf/Makefile | 13 +++++++++----
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
index 1733a6e93a07..ef083602b73a 100644
--- a/tools/bpf/resolve_btfids/Makefile
+++ b/tools/bpf/resolve_btfids/Makefile
@@ -65,6 +65,9 @@ $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OU
 LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null)
 LIBELF_LIBS  := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
 
+ZLIB_LIBS  := $(shell $(HOSTPKG_CONFIG) zlib --libs 2>/dev/null || echo -lz)
+ZSTD_LIBS  := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null || echo -lzstd)
+
 HOSTCFLAGS_resolve_btfids += -g \
           -I$(srctree)/tools/include \
           -I$(srctree)/tools/include/uapi \
@@ -73,7 +76,7 @@ HOSTCFLAGS_resolve_btfids += -g \
           $(LIBELF_FLAGS) \
           -Wall -Werror
 
-LIBS = $(LIBELF_LIBS) -lz
+LIBS = $(LIBELF_LIBS) $(ZLIB_LIBS) $(ZSTD_LIBS)
 
 export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR
 include $(srctree)/tools/build/Makefile.include
@@ -83,7 +86,7 @@ $(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
 
 $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN)
 	$(call msg,LINK,$@)
-	$(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
+	$(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) $(EXTRA_LDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
 
 clean_objects := $(wildcard $(OUTPUT)/*.o                \
                             $(OUTPUT)/.*.o.cmd           \
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 6776158f1f3e..72a9ba41f95e 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -27,7 +27,11 @@ ifneq ($(wildcard $(GENHDR)),)
 endif
 
 BPF_GCC		?= $(shell command -v bpf-gcc;)
+ifdef ASAN
+SAN_CFLAGS 	?= -fsanitize=address -fno-omit-frame-pointer
+else
 SAN_CFLAGS	?=
+endif
 SAN_LDFLAGS	?= $(SAN_CFLAGS)
 RELEASE		?=
 OPT_FLAGS	?= $(if $(RELEASE),-O2,-O0)
@@ -326,8 +330,8 @@ $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile)    \
 		    $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool
 	$(Q)$(MAKE) $(submake_extras)  -C $(BPFTOOLDIR)			       \
 		    ARCH= CROSS_COMPILE= CC="$(HOSTCC)" LD="$(HOSTLD)" 	       \
-		    EXTRA_CFLAGS='-g $(OPT_FLAGS) $(EXTRA_CFLAGS)'	       \
-		    EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)'			       \
+		    EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)'	       \
+		    EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)'			       \
 		    OUTPUT=$(HOST_BUILD_DIR)/bpftool/			       \
 		    LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/		       \
 		    LIBBPF_DESTDIR=$(HOST_SCRATCH_DIR)/			       \
@@ -338,8 +342,8 @@ $(CROSS_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile)	\
 		    $(BPFOBJ) | $(BUILD_DIR)/bpftool
 	$(Q)$(MAKE) $(submake_extras)  -C $(BPFTOOLDIR)				\
 		    ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)			\
-		    EXTRA_CFLAGS='-g $(OPT_FLAGS) $(EXTRA_CFLAGS)'		\
-		    EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)'				\
+		    EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)'	       \
+		    EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)'			       \
 		    OUTPUT=$(BUILD_DIR)/bpftool/				\
 		    LIBBPF_OUTPUT=$(BUILD_DIR)/libbpf/				\
 		    LIBBPF_DESTDIR=$(SCRATCH_DIR)/				\
@@ -404,6 +408,7 @@ $(RESOLVE_BTFIDS): $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/resolve_btfids	\
 	$(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/resolve_btfids	\
 		CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" \
 		LIBBPF_INCLUDE=$(HOST_INCLUDE_DIR) \
+		EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' \
 		OUTPUT=$(HOST_BUILD_DIR)/resolve_btfids/ BPFOBJ=$(HOST_BPFOBJ)
 
 # Get Clang's default includes on this system, as opposed to those seen by
-- 
2.53.0


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

* [PATCH bpf v4 07/20] resolve_btfids: Fix memory leaks reported by ASAN
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (5 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 06/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 08/20] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Running resolve_btfids with ASAN reveals memory leaks in btf_id
handling.

- Change get_id() to use a local buffer
- Make btf_id__add() strdup the name internally
- Add btf_id__free_all() that frees all nodese of a tree
- Call the cleanup function on exit for every tree

Acked-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/resolve_btfids/main.c | 81 ++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 27 deletions(-)

diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index ca7fcd03efb6..5208f650080f 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -226,7 +226,7 @@ static struct btf_id *btf_id__find(struct rb_root *root, const char *name)
 }
 
 static struct btf_id *__btf_id__add(struct rb_root *root,
-				    char *name,
+				    const char *name,
 				    enum btf_id_kind kind,
 				    bool unique)
 {
@@ -250,7 +250,11 @@ static struct btf_id *__btf_id__add(struct rb_root *root,
 	id = zalloc(sizeof(*id));
 	if (id) {
 		pr_debug("adding symbol %s\n", name);
-		id->name = name;
+		id->name = strdup(name);
+		if (!id->name) {
+			free(id);
+			return NULL;
+		}
 		id->kind = kind;
 		rb_link_node(&id->rb_node, parent, p);
 		rb_insert_color(&id->rb_node, root);
@@ -258,17 +262,21 @@ static struct btf_id *__btf_id__add(struct rb_root *root,
 	return id;
 }
 
-static inline struct btf_id *btf_id__add(struct rb_root *root, char *name, enum btf_id_kind kind)
+static inline struct btf_id *btf_id__add(struct rb_root *root,
+					 const char *name,
+					 enum btf_id_kind kind)
 {
 	return __btf_id__add(root, name, kind, false);
 }
 
-static inline struct btf_id *btf_id__add_unique(struct rb_root *root, char *name, enum btf_id_kind kind)
+static inline struct btf_id *btf_id__add_unique(struct rb_root *root,
+						const char *name,
+						enum btf_id_kind kind)
 {
 	return __btf_id__add(root, name, kind, true);
 }
 
-static char *get_id(const char *prefix_end)
+static int get_id(const char *prefix_end, char *buf, size_t buf_sz)
 {
 	/*
 	 * __BTF_ID__func__vfs_truncate__0
@@ -277,28 +285,28 @@ static char *get_id(const char *prefix_end)
 	 */
 	int len = strlen(prefix_end);
 	int pos = sizeof("__") - 1;
-	char *p, *id;
+	char *p;
 
 	if (pos >= len)
-		return NULL;
+		return -1;
 
-	id = strdup(prefix_end + pos);
-	if (id) {
-		/*
-		 * __BTF_ID__func__vfs_truncate__0
-		 * id =            ^
-		 *
-		 * cut the unique id part
-		 */
-		p = strrchr(id, '_');
-		p--;
-		if (*p != '_') {
-			free(id);
-			return NULL;
-		}
-		*p = '\0';
-	}
-	return id;
+	if (len - pos >= buf_sz)
+		return -1;
+
+	strcpy(buf, prefix_end + pos);
+	/*
+	 * __BTF_ID__func__vfs_truncate__0
+	 * buf =           ^
+	 *
+	 * cut the unique id part
+	 */
+	p = strrchr(buf, '_');
+	p--;
+	if (*p != '_')
+		return -1;
+	*p = '\0';
+
+	return 0;
 }
 
 static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind kind)
@@ -335,10 +343,9 @@ static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind k
 
 static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
 {
-	char *id;
+	char id[KSYM_NAME_LEN];
 
-	id = get_id(name + size);
-	if (!id) {
+	if (get_id(name + size, id, sizeof(id))) {
 		pr_err("FAILED to parse symbol name: %s\n", name);
 		return NULL;
 	}
@@ -346,6 +353,21 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
 	return btf_id__add(root, id, BTF_ID_KIND_SYM);
 }
 
+static void btf_id__free_all(struct rb_root *root)
+{
+	struct rb_node *next;
+	struct btf_id *id;
+
+	next = rb_first(root);
+	while (next) {
+		id = rb_entry(next, struct btf_id, rb_node);
+		next = rb_next(&id->rb_node);
+		rb_erase(&id->rb_node, root);
+		free(id->name);
+		free(id);
+	}
+}
+
 static void bswap_32_data(void *data, u32 nr_bytes)
 {
 	u32 cnt, i;
@@ -1547,6 +1569,11 @@ int main(int argc, const char **argv)
 out:
 	btf__free(obj.base_btf);
 	btf__free(obj.btf);
+	btf_id__free_all(&obj.structs);
+	btf_id__free_all(&obj.unions);
+	btf_id__free_all(&obj.typedefs);
+	btf_id__free_all(&obj.funcs);
+	btf_id__free_all(&obj.sets);
 	if (obj.efile.elf) {
 		elf_end(obj.efile.elf);
 		close(obj.efile.fd);
-- 
2.53.0


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

* [PATCH bpf v4 08/20] selftests/bpf: Add DENYLIST.asan
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (6 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 07/20] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Add a denylist file for tests that should be skipped when built with
userspace ASAN:

    $ make ... SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"

Skip the following tests:

- *arena*: userspace ASAN does not understand BPF arena maps and gets
  confused particularly when map_extra is non-zero
  - non-zero map_extra leads to mmap with MAP_FIXED, and ASAN treats
    this as an unknown memory region
- task_local_data: ASAN complains about "incorrect" aligned_alloc()
  usage, but it's intentional in the test
- uprobe_multi_test: very slow with ASAN enabled

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/DENYLIST.asan | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/DENYLIST.asan

diff --git a/tools/testing/selftests/bpf/DENYLIST.asan b/tools/testing/selftests/bpf/DENYLIST.asan
new file mode 100644
index 000000000000..d7fe372a2293
--- /dev/null
+++ b/tools/testing/selftests/bpf/DENYLIST.asan
@@ -0,0 +1,3 @@
+*arena*
+task_local_data
+uprobe_multi_test
-- 
2.53.0


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

* [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (7 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 08/20] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 23:23   ` Eduard Zingerman
  2026-02-23 19:07 ` [PATCH bpf v4 10/20] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN reported a memory leak in bpf_get_ksyms(): it allocates a struct
ksyms internally and never frees it.

Move struct ksyms to trace_helpers.h and return it from the
bpf_get_ksyms(), giving ownership to the caller. Add filtered_syms and
filtered_cnt fields to the ksyms to hold the filtered array of
symbols, previously returned by bpf_get_ksyms().

Fixup the call sites: kprobe_multi_test and bench_trigger.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/benchs/bench_trigger.c      | 14 ++++++-----
 .../bpf/prog_tests/kprobe_multi_test.c        | 12 ++++------
 tools/testing/selftests/bpf/trace_helpers.c   | 23 ++++++++++---------
 tools/testing/selftests/bpf/trace_helpers.h   | 11 +++++++--
 4 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c
index aeec9edd3851..f74b313d6ae4 100644
--- a/tools/testing/selftests/bpf/benchs/bench_trigger.c
+++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c
@@ -230,8 +230,8 @@ static void trigger_fentry_setup(void)
 static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
 {
 	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
-	char **syms = NULL;
-	size_t cnt = 0;
+	struct bpf_link *link = NULL;
+	struct ksyms *ksyms = NULL;
 
 	/* Some recursive functions will be skipped in
 	 * bpf_get_ksyms -> skip_entry, as they can introduce sufficient
@@ -241,16 +241,18 @@ static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
 	 * So, don't run the kprobe-multi-all and kretprobe-multi-all on
 	 * a debug kernel.
 	 */
-	if (bpf_get_ksyms(&syms, &cnt, true)) {
+	if (bpf_get_ksyms(&ksyms, true)) {
 		fprintf(stderr, "failed to get ksyms\n");
 		exit(1);
 	}
 
-	opts.syms = (const char **) syms;
-	opts.cnt = cnt;
+	opts.syms = (const char **)ksyms->filtered_syms;
+	opts.cnt = ksyms->filtered_cnt;
 	opts.retprobe = kretprobe;
 	/* attach empty to all the kernel functions except bpf_get_numa_node_id. */
-	if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) {
+	link = bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts);
+	free_kallsyms_local(ksyms);
+	if (!link) {
 		fprintf(stderr, "failed to attach bpf_program__attach_kprobe_multi_opts to all\n");
 		exit(1);
 	}
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 9caef222e528..f81dcd609ee9 100644
--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
@@ -456,25 +456,23 @@ static void test_kprobe_multi_bench_attach(bool kernel)
 {
 	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
 	struct kprobe_multi_empty *skel = NULL;
-	char **syms = NULL;
-	size_t cnt = 0;
+	struct ksyms *ksyms = NULL;
 
-	if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, kernel), "bpf_get_ksyms"))
+	if (!ASSERT_OK(bpf_get_ksyms(&ksyms, kernel), "bpf_get_ksyms"))
 		return;
 
 	skel = kprobe_multi_empty__open_and_load();
 	if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
 		goto cleanup;
 
-	opts.syms = (const char **) syms;
-	opts.cnt = cnt;
+	opts.syms = (const char **)ksyms->filtered_syms;
+	opts.cnt = ksyms->filtered_cnt;
 
 	do_bench_test(skel, &opts);
 
 cleanup:
 	kprobe_multi_empty__destroy(skel);
-	if (syms)
-		free(syms);
+	free_kallsyms_local(ksyms);
 }
 
 static void test_kprobe_multi_bench_attach_addr(bool kernel)
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index eeaab7013ca2..0e63daf83ed5 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -24,12 +24,6 @@
 #define TRACEFS_PIPE	"/sys/kernel/tracing/trace_pipe"
 #define DEBUGFS_PIPE	"/sys/kernel/debug/tracing/trace_pipe"
 
-struct ksyms {
-	struct ksym *syms;
-	size_t sym_cap;
-	size_t sym_cnt;
-};
-
 static struct ksyms *ksyms;
 static pthread_mutex_t ksyms_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -54,6 +48,8 @@ void free_kallsyms_local(struct ksyms *ksyms)
 	if (!ksyms)
 		return;
 
+	free(ksyms->filtered_syms);
+
 	if (!ksyms->syms) {
 		free(ksyms);
 		return;
@@ -610,7 +606,7 @@ static int search_kallsyms_compare(const void *p1, const struct ksym *p2)
 	return compare_name(p1, p2->name);
 }
 
-int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
+int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel)
 {
 	size_t cap = 0, cnt = 0;
 	char *name = NULL, *ksym_name, **syms = NULL;
@@ -637,8 +633,10 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
 	else
 		f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");
 
-	if (!f)
+	if (!f) {
+		free_kallsyms_local(ksyms);
 		return -EINVAL;
+	}
 
 	map = hashmap__new(symbol_hash, symbol_equal, NULL);
 	if (IS_ERR(map)) {
@@ -679,15 +677,18 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
 		syms[cnt++] = ksym_name;
 	}
 
-	*symsp = syms;
-	*cntp = cnt;
+	ksyms->filtered_syms = syms;
+	ksyms->filtered_cnt = cnt;
+	*ksymsp = ksyms;
 
 error:
 	free(name);
 	fclose(f);
 	hashmap__free(map);
-	if (err)
+	if (err) {
 		free(syms);
+		free_kallsyms_local(ksyms);
+	}
 	return err;
 }
 
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
index a5576b2dfc26..d5bf1433675d 100644
--- a/tools/testing/selftests/bpf/trace_helpers.h
+++ b/tools/testing/selftests/bpf/trace_helpers.h
@@ -23,7 +23,14 @@ struct ksym {
 	long addr;
 	char *name;
 };
-struct ksyms;
+
+struct ksyms {
+	struct ksym *syms;
+	size_t sym_cap;
+	size_t sym_cnt;
+	char **filtered_syms;
+	size_t filtered_cnt;
+};
 
 typedef int (*ksym_cmp_t)(const void *p1, const void *p2);
 typedef int (*ksym_search_cmp_t)(const void *p1, const struct ksym *p2);
@@ -53,7 +60,7 @@ ssize_t get_rel_offset(uintptr_t addr);
 
 int read_build_id(const char *path, char *build_id, size_t size);
 
-int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel);
+int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel);
 int bpf_get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel);
 
 #endif
-- 
2.53.0


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

* [PATCH bpf v4 10/20] selftests/bpf: Fix memory leaks in tests
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (8 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Fix trivial memory leaks detected by userspace ASAN:
  - htab_update: free value buffer in test_reenter_update cleanup
  - test_xsk: inline pkt_stream_replace() in testapp_stats_rx_full()
    and testapp_stats_fill_empty()
  - testing_helpers: free buffer allocated by getline() in
    parse_test_list_file

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/htab_update.c    |  1 +
 .../selftests/bpf/prog_tests/test_xsk.c       | 24 +++++++++++++++----
 tools/testing/selftests/bpf/testing_helpers.c |  1 +
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/htab_update.c b/tools/testing/selftests/bpf/prog_tests/htab_update.c
index d0b405eb2966..ea1a6766fbe9 100644
--- a/tools/testing/selftests/bpf/prog_tests/htab_update.c
+++ b/tools/testing/selftests/bpf/prog_tests/htab_update.c
@@ -61,6 +61,7 @@ static void test_reenter_update(void)
 
 	ASSERT_EQ(skel->bss->update_err, -EDEADLK, "no reentrancy");
 out:
+	free(value);
 	htab_update__destroy(skel);
 }
 
diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index bab4a31621c7..7e38ec6e656b 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -2003,9 +2003,17 @@ int testapp_stats_tx_invalid_descs(struct test_spec *test)
 
 int testapp_stats_rx_full(struct test_spec *test)
 {
-	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
+	struct pkt_stream *tmp;
+
+	tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
+	if (!tmp)
+		return TEST_FAILURE;
+	test->ifobj_tx->xsk->pkt_stream = tmp;
+
+	tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
+	if (!tmp)
 		return TEST_FAILURE;
-	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
+	test->ifobj_rx->xsk->pkt_stream = tmp;
 
 	test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
 	test->ifobj_rx->release_rx = false;
@@ -2015,9 +2023,17 @@ int testapp_stats_rx_full(struct test_spec *test)
 
 int testapp_stats_fill_empty(struct test_spec *test)
 {
-	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
+	struct pkt_stream *tmp;
+
+	tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
+	if (!tmp)
+		return TEST_FAILURE;
+	test->ifobj_tx->xsk->pkt_stream = tmp;
+
+	tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
+	if (!tmp)
 		return TEST_FAILURE;
-	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
+	test->ifobj_rx->xsk->pkt_stream = tmp;
 
 	test->ifobj_rx->use_fill_ring = false;
 	test->ifobj_rx->validation_func = validate_fill_empty;
diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c
index 16eb37e5bad6..66af0d13751a 100644
--- a/tools/testing/selftests/bpf/testing_helpers.c
+++ b/tools/testing/selftests/bpf/testing_helpers.c
@@ -212,6 +212,7 @@ int parse_test_list_file(const char *path,
 			break;
 	}
 
+	free(buf);
 	fclose(f);
 	return err;
 }
-- 
2.53.0


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

* [PATCH bpf v4 11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (9 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 10/20] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 12/20] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

The Close() macro uses the passed in expression three times, which
leads to repeated execution in case it has side effects. That is,
Close(i--) would decrement i three times.

ASAN caught a stack-buffer-undeflow error at a point where this was
overlooked. Fix it.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/fd_array.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/fd_array.c b/tools/testing/selftests/bpf/prog_tests/fd_array.c
index c534b4d5f9da..3078d8264deb 100644
--- a/tools/testing/selftests/bpf/prog_tests/fd_array.c
+++ b/tools/testing/selftests/bpf/prog_tests/fd_array.c
@@ -412,8 +412,8 @@ static void check_fd_array_cnt__fd_array_too_big(void)
 	ASSERT_EQ(prog_fd, -E2BIG, "prog should have been rejected with -E2BIG");
 
 cleanup_fds:
-	while (i > 0)
-		Close(extra_fds[--i]);
+	while (i-- > 0)
+		Close(extra_fds[i]);
 }
 
 void test_fd_array_cnt(void)
-- 
2.53.0


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

* [PATCH bpf v4 12/20] veristat: Fix a memory leak for preset ENUMERATOR
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (10 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 13/20] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN detected a memory leak in veristat. The cleanup code handling
ENUMERATOR value missed freeing strdup-ed svalue. Fix it.

Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/veristat.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/testing/selftests/bpf/veristat.c b/tools/testing/selftests/bpf/veristat.c
index 1be1e353d40a..75f85e0362f5 100644
--- a/tools/testing/selftests/bpf/veristat.c
+++ b/tools/testing/selftests/bpf/veristat.c
@@ -3378,6 +3378,8 @@ int main(int argc, char **argv)
 			}
 		}
 		free(env.presets[i].atoms);
+		if (env.presets[i].value.type == ENUMERATOR)
+			free(env.presets[i].value.svalue);
 	}
 	free(env.presets);
 	return -err;
-- 
2.53.0


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

* [PATCH bpf v4 13/20] selftests/bpf: Fix use-after-free in xdp_metadata test
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (11 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 12/20] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 14/20] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN reported a use-after-free in close_xsk().

The xsk->socket internally references xsk->umem via socket->ctx->umem,
so the socket must be deleted before the umem. Fix the order of
operations in close_xsk().

Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/xdp_metadata.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c b/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
index 19f92affc2da..5c31054ad4a4 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
@@ -126,10 +126,10 @@ static int open_xsk(int ifindex, struct xsk *xsk)
 
 static void close_xsk(struct xsk *xsk)
 {
-	if (xsk->umem)
-		xsk_umem__delete(xsk->umem);
 	if (xsk->socket)
 		xsk_socket__delete(xsk->socket);
+	if (xsk->umem)
+		xsk_umem__delete(xsk->umem);
 	munmap(xsk->umem_area, UMEM_SIZE);
 }
 
-- 
2.53.0


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

* [PATCH bpf v4 14/20] selftests/bpf: Fix double thread join in uprobe_multi_test
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (12 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 13/20] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 15/20] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN reported a "joining already joined thread" error. The
release_child() may be called multiple times for the same struct
child.

Fix by resetting child->thread to 0 after pthread_join.

Also memset(0) static child variable in test_attach_api().

Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
index 2ee17ef1dae2..56cbea280fbd 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
@@ -62,8 +62,10 @@ static void release_child(struct child *child)
 		return;
 	close(child->go[1]);
 	close(child->go[0]);
-	if (child->thread)
+	if (child->thread) {
 		pthread_join(child->thread, NULL);
+		child->thread = 0;
+	}
 	close(child->c2p[0]);
 	close(child->c2p[1]);
 	if (child->pid > 0)
@@ -331,6 +333,8 @@ test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi
 {
 	static struct child child;
 
+	memset(&child, 0, sizeof(child));
+
 	/* no pid filter */
 	__test_attach_api(binary, pattern, opts, NULL);
 
-- 
2.53.0


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

* [PATCH bpf v4 15/20] selftests/bpf: Fix resource leaks caused by missing cleanups
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (13 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 14/20] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 16/20] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN reported a number of resource leaks:
  - Add missing  *__destroy(skel) calls
  - Replace bpf_link__detach() with bpf_link__destroy() where appropriate
  - cgrp_local_storage: Add bpf_link__destroy() when bpf_iter_create fails
  - dynptr: Add missing bpf_object__close()

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../bpf/prog_tests/cgrp_local_storage.c       |  4 ++-
 .../testing/selftests/bpf/prog_tests/dynptr.c |  5 +++-
 .../selftests/bpf/prog_tests/sockmap_basic.c  | 28 +++++++++----------
 .../selftests/bpf/prog_tests/sockmap_listen.c |  2 +-
 .../bpf/prog_tests/struct_ops_private_stack.c |  4 +--
 .../selftests/bpf/prog_tests/tc_opts.c        |  6 ++--
 .../selftests/bpf/prog_tests/test_tc_tunnel.c |  5 +++-
 7 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c b/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c
index 9015e2c2ab12..478a77cb67e6 100644
--- a/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c
+++ b/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c
@@ -202,7 +202,7 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id)
 
 	iter_fd = bpf_iter_create(bpf_link__fd(link));
 	if (!ASSERT_GE(iter_fd, 0, "iter_create"))
-		goto out;
+		goto out_link;
 
 	/* trigger the program run */
 	(void)read(iter_fd, buf, sizeof(buf));
@@ -210,6 +210,8 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id)
 	ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
 
 	close(iter_fd);
+out_link:
+	bpf_link__destroy(link);
 out:
 	cgrp_ls_sleepable__destroy(skel);
 }
diff --git a/tools/testing/selftests/bpf/prog_tests/dynptr.c b/tools/testing/selftests/bpf/prog_tests/dynptr.c
index b9f86cb91e81..5fda11590708 100644
--- a/tools/testing/selftests/bpf/prog_tests/dynptr.c
+++ b/tools/testing/selftests/bpf/prog_tests/dynptr.c
@@ -137,11 +137,14 @@ static void verify_success(const char *prog_name, enum test_setup_type setup_typ
 		);
 
 		link = bpf_program__attach(prog);
-		if (!ASSERT_OK_PTR(link, "bpf_program__attach"))
+		if (!ASSERT_OK_PTR(link, "bpf_program__attach")) {
+			bpf_object__close(obj);
 			goto cleanup;
+		}
 
 		err = bpf_prog_test_run_opts(aux_prog_fd, &topts);
 		bpf_link__destroy(link);
+		bpf_object__close(obj);
 
 		if (!ASSERT_OK(err, "test_run"))
 			goto cleanup;
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
index 256707e7d20d..dd3c757859f6 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
@@ -204,7 +204,7 @@ static void test_skmsg_helpers_with_link(enum bpf_map_type map_type)
 	/* Fail since bpf_link for the same prog type has been created. */
 	link2 = bpf_program__attach_sockmap(prog_clone, map);
 	if (!ASSERT_ERR_PTR(link2, "bpf_program__attach_sockmap")) {
-		bpf_link__detach(link2);
+		bpf_link__destroy(link2);
 		goto out;
 	}
 
@@ -230,7 +230,7 @@ static void test_skmsg_helpers_with_link(enum bpf_map_type map_type)
 	if (!ASSERT_OK(err, "bpf_link_update"))
 		goto out;
 out:
-	bpf_link__detach(link);
+	bpf_link__destroy(link);
 	test_skmsg_load_helpers__destroy(skel);
 }
 
@@ -417,7 +417,7 @@ static void test_sockmap_skb_verdict_attach_with_link(void)
 	if (!ASSERT_OK_PTR(link, "bpf_program__attach_sockmap"))
 		goto out;
 
-	bpf_link__detach(link);
+	bpf_link__destroy(link);
 
 	err = bpf_prog_attach(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT, 0);
 	if (!ASSERT_OK(err, "bpf_prog_attach"))
@@ -426,7 +426,7 @@ static void test_sockmap_skb_verdict_attach_with_link(void)
 	/* Fail since attaching with the same prog/map has been done. */
 	link = bpf_program__attach_sockmap(prog, map);
 	if (!ASSERT_ERR_PTR(link, "bpf_program__attach_sockmap"))
-		bpf_link__detach(link);
+		bpf_link__destroy(link);
 
 	err = bpf_prog_detach2(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT);
 	if (!ASSERT_OK(err, "bpf_prog_detach2"))
@@ -747,13 +747,13 @@ static void test_sockmap_skb_verdict_peek_with_link(void)
 	test_sockmap_skb_verdict_peek_helper(map);
 	ASSERT_EQ(pass->bss->clone_called, 1, "clone_called");
 out:
-	bpf_link__detach(link);
+	bpf_link__destroy(link);
 	test_sockmap_pass_prog__destroy(pass);
 }
 
 static void test_sockmap_unconnected_unix(void)
 {
-	int err, map, stream = 0, dgram = 0, zero = 0;
+	int err, map, stream = -1, dgram = -1, zero = 0;
 	struct test_sockmap_pass_prog *skel;
 
 	skel = test_sockmap_pass_prog__open_and_load();
@@ -764,22 +764,22 @@ static void test_sockmap_unconnected_unix(void)
 
 	stream = xsocket(AF_UNIX, SOCK_STREAM, 0);
 	if (stream < 0)
-		return;
+		goto out;
 
 	dgram = xsocket(AF_UNIX, SOCK_DGRAM, 0);
-	if (dgram < 0) {
-		close(stream);
-		return;
-	}
+	if (dgram < 0)
+		goto out;
 
 	err = bpf_map_update_elem(map, &zero, &stream, BPF_ANY);
-	ASSERT_ERR(err, "bpf_map_update_elem(stream)");
+	if (!ASSERT_ERR(err, "bpf_map_update_elem(stream)"))
+		goto out;
 
 	err = bpf_map_update_elem(map, &zero, &dgram, BPF_ANY);
 	ASSERT_OK(err, "bpf_map_update_elem(dgram)");
-
+out:
 	close(stream);
 	close(dgram);
+	test_sockmap_pass_prog__destroy(skel);
 }
 
 static void test_sockmap_many_socket(void)
@@ -1027,7 +1027,7 @@ static void test_sockmap_skb_verdict_vsock_poll(void)
 	if (xrecv_nonblock(conn, &buf, 1, 0) != 1)
 		FAIL("xrecv_nonblock");
 detach:
-	bpf_link__detach(link);
+	bpf_link__destroy(link);
 close:
 	xclose(conn);
 	xclose(peer);
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
index f1bdccc7e4e7..cc0c68bab907 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
@@ -899,7 +899,7 @@ static void test_msg_redir_to_listening_with_link(struct test_sockmap_listen *sk
 
 	redir_to_listening(family, sotype, sock_map, verdict_map, REDIR_EGRESS);
 
-	bpf_link__detach(link);
+	bpf_link__destroy(link);
 }
 
 static void redir_partial(int family, int sotype, int sock_map, int parser_map)
diff --git a/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c b/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c
index 4006879ca3fe..d42123a0fb16 100644
--- a/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c
+++ b/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c
@@ -54,9 +54,7 @@ static void test_private_stack_fail(void)
 	}
 
 	err = struct_ops_private_stack_fail__load(skel);
-	if (!ASSERT_ERR(err, "struct_ops_private_stack_fail__load"))
-		goto cleanup;
-	return;
+	ASSERT_ERR(err, "struct_ops_private_stack_fail__load");
 
 cleanup:
 	struct_ops_private_stack_fail__destroy(skel);
diff --git a/tools/testing/selftests/bpf/prog_tests/tc_opts.c b/tools/testing/selftests/bpf/prog_tests/tc_opts.c
index dd7a138d8c3d..2955750ddada 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_opts.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_opts.c
@@ -1360,10 +1360,8 @@ static void test_tc_opts_dev_cleanup_target(int target)
 
 	assert_mprog_count_ifindex(ifindex, target, 4);
 
-	ASSERT_OK(system("ip link del dev tcx_opts1"), "del veth");
-	ASSERT_EQ(if_nametoindex("tcx_opts1"), 0, "dev1_removed");
-	ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed");
-	return;
+	goto cleanup;
+
 cleanup3:
 	err = bpf_prog_detach_opts(fd3, loopback, target, &optd);
 	ASSERT_OK(err, "prog_detach");
diff --git a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
index 0fe0a8f62486..7fc4d7dd70ef 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
@@ -699,7 +699,7 @@ void test_tc_tunnel(void)
 		return;
 
 	if (!ASSERT_OK(setup(), "global setup"))
-		return;
+		goto out;
 
 	for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) {
 		cfg = &subtests_cfg[i];
@@ -711,4 +711,7 @@ void test_tc_tunnel(void)
 		subtest_cleanup(cfg);
 	}
 	cleanup();
+
+out:
+	test_tc_tunnel__destroy(skel);
 }
-- 
2.53.0


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

* [PATCH bpf v4 16/20] selftests/bpf: Free bpf_object in test_sysctl
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (14 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 15/20] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:07 ` [PATCH bpf v4 17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

ASAN reported a resource leak due to the bpf_object not being tracked
in test_sysctl. Add obj field to struct sysctl_test to properly clean
it up.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/test_sysctl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
index 273dd41ca09e..2a1ff821bc97 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
@@ -27,6 +27,7 @@ struct sysctl_test {
 		OP_EPERM,
 		SUCCESS,
 	} result;
+	struct bpf_object *obj;
 };
 
 static struct sysctl_test tests[] = {
@@ -1471,6 +1472,7 @@ static int load_sysctl_prog_file(struct sysctl_test *test)
 		return -1;
 	}
 
+	test->obj = obj;
 	return prog_fd;
 }
 
@@ -1573,6 +1575,7 @@ static int run_test_case(int cgfd, struct sysctl_test *test)
 	/* Detaching w/o checking return code: best effort attempt. */
 	if (progfd != -1)
 		bpf_prog_detach(cgfd, atype);
+	bpf_object__close(test->obj);
 	close(progfd);
 	printf("[%s]\n", err ? "FAIL" : "PASS");
 	return err;
-- 
2.53.0


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

* [PATCH bpf v4 17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (15 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 16/20] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
@ 2026-02-23 19:07 ` Ihor Solodrai
  2026-02-23 19:11 ` [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
  2026-02-24  3:00 ` [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN patchwork-bot+netdevbpf
  18 siblings, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:07 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

Compiler cannot infer upper bound for labels.cnt and warns about
potential buffer overflow in snprintf. Add an explicit bounds
check (... && i < MAX_LOCAL_LABELS) in the loop condition to fix the
warning.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../testing/selftests/bpf/jit_disasm_helpers.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c
index febd6b12e372..364c557c5115 100644
--- a/tools/testing/selftests/bpf/jit_disasm_helpers.c
+++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c
@@ -122,15 +122,15 @@ static int disasm_one_func(FILE *text_out, uint8_t *image, __u32 len)
 		pc += cnt;
 	}
 	qsort(labels.pcs, labels.cnt, sizeof(*labels.pcs), cmp_u32);
-	for (i = 0; i < labels.cnt; ++i)
-		/* gcc is unable to infer upper bound for labels.cnt and assumes
-		 * it to be U32_MAX. U32_MAX takes 10 decimal digits.
-		 * snprintf below prints into labels.names[*],
-		 * which has space only for two digits and a letter.
-		 * To avoid truncation warning use (i % MAX_LOCAL_LABELS),
-		 * which informs gcc about printed value upper bound.
-		 */
-		snprintf(labels.names[i], sizeof(labels.names[i]), "L%d", i % MAX_LOCAL_LABELS);
+	/* gcc is unable to infer upper bound for labels.cnt and
+	 * assumes it to be U32_MAX. U32_MAX takes 10 decimal digits.
+	 * snprintf below prints into labels.names[*], which has space
+	 * only for two digits and a letter.  To avoid truncation
+	 * warning use (i < MAX_LOCAL_LABELS), which informs gcc about
+	 * printed value upper bound.
+	 */
+	for (i = 0; i < labels.cnt && i < MAX_LOCAL_LABELS; ++i)
+		snprintf(labels.names[i], sizeof(labels.names[i]), "L%d", i);
 
 	/* now print with labels */
 	labels.print_phase = true;
-- 
2.53.0


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

* [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (16 preceding siblings ...)
  2026-02-23 19:07 ` [PATCH bpf v4 17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
@ 2026-02-23 19:11 ` Ihor Solodrai
  2026-02-23 19:11   ` [PATCH bpf v4 19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
  2026-02-23 19:11   ` [PATCH bpf v4 20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
  2026-02-24  3:00 ` [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN patchwork-bot+netdevbpf
  18 siblings, 2 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

- kmem_cache_iter: remove unnecessary debug output
- lwt_seg6local: change the type of foobar to char[]
  - the sizeof(foobar) returned the pointer size and not a string
    length as intended
- verifier_log: increase prog_name buffer size in verif_log_subtest()
  - compiler has a conservative estimate of fixed_log_sz value, making
    ASAN complain on snprint() call

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c | 7 ++-----
 tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c   | 2 +-
 tools/testing/selftests/bpf/prog_tests/verifier_log.c    | 2 +-
 3 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
index 6e35e13c2022..399fe9103f83 100644
--- a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
+++ b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
@@ -104,11 +104,8 @@ void test_kmem_cache_iter(void)
 	if (!ASSERT_GE(iter_fd, 0, "iter_create"))
 		goto destroy;
 
-	memset(buf, 0, sizeof(buf));
-	while (read(iter_fd, buf, sizeof(buf)) > 0) {
-		/* Read out all contents */
-		printf("%s", buf);
-	}
+	while (read(iter_fd, buf, sizeof(buf)) > 0)
+		; /* Read out all contents */
 
 	/* Next reads should return 0 */
 	ASSERT_EQ(read(iter_fd, buf, sizeof(buf)), 0, "read");
diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c b/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c
index 3bc730b7c7fa..1b25d5c5f8fb 100644
--- a/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c
+++ b/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c
@@ -117,7 +117,7 @@ void test_lwt_seg6local(void)
 	const char *ns1 = NETNS_BASE "1";
 	const char *ns6 = NETNS_BASE "6";
 	struct nstoken *nstoken = NULL;
-	const char *foobar = "foobar";
+	const char foobar[] = "foobar";
 	ssize_t bytes;
 	int sfd, cfd;
 	char buf[7];
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier_log.c b/tools/testing/selftests/bpf/prog_tests/verifier_log.c
index 8337c6bc5b95..aaa2854974c0 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier_log.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier_log.c
@@ -47,7 +47,7 @@ static int load_prog(struct bpf_prog_load_opts *opts, bool expect_load_error)
 static void verif_log_subtest(const char *name, bool expect_load_error, int log_level)
 {
 	LIBBPF_OPTS(bpf_prog_load_opts, opts);
-	char *exp_log, prog_name[16], op_name[32];
+	char *exp_log, prog_name[24], op_name[32];
 	struct test_log_buf *skel;
 	struct bpf_program *prog;
 	size_t fixed_log_sz;
-- 
2.53.0


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

* [PATCH bpf v4 19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
  2026-02-23 19:11 ` [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
@ 2026-02-23 19:11   ` Ihor Solodrai
  2026-02-23 19:11   ` [PATCH bpf v4 20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
  1 sibling, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

The bpftool_maps_access and bpftool_metadata tests may fail on BPF CI
with "command not found", depending on a workflow.
This happens because detect_bpftool_path() only checks two hardcoded
relative paths:
  - ./tools/sbin/bpftool
  - ../tools/sbin/bpftool

Add support for a BPFTOOL environment variable that allows specifying
the exact path to the bpftool binary.

Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/bpftool_helpers.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/bpftool_helpers.c b/tools/testing/selftests/bpf/bpftool_helpers.c
index 595a636fa13b..929fc257f431 100644
--- a/tools/testing/selftests/bpf/bpftool_helpers.c
+++ b/tools/testing/selftests/bpf/bpftool_helpers.c
@@ -14,6 +14,17 @@
 static int detect_bpftool_path(char *buffer, size_t size)
 {
 	char tmp[BPFTOOL_PATH_MAX_LEN];
+	const char *env_path;
+
+	/* First, check if BPFTOOL environment variable is set */
+	env_path = getenv("BPFTOOL");
+	if (env_path && access(env_path, X_OK) == 0) {
+		strscpy(buffer, env_path, size);
+		return 0;
+	} else if (env_path) {
+		fprintf(stderr, "bpftool '%s' doesn't exist or is not executable\n", env_path);
+		return 1;
+	}
 
 	/* Check default bpftool location (will work if we are running the
 	 * default flavor of test_progs)
@@ -33,7 +44,7 @@ static int detect_bpftool_path(char *buffer, size_t size)
 		return 0;
 	}
 
-	/* Failed to find bpftool binary */
+	fprintf(stderr, "Failed to detect bpftool path, use BPFTOOL env var to override\n");
 	return 1;
 }
 
-- 
2.53.0


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

* [PATCH bpf v4 20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN
  2026-02-23 19:11 ` [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
  2026-02-23 19:11   ` [PATCH bpf v4 19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
@ 2026-02-23 19:11   ` Ihor Solodrai
  1 sibling, 0 replies; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 19:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

test_progs has custom SIGSEGV handler, which interferes with the
address sanitizer [1]. Add an #ifndef to avoid this.

Additionally, declare an __asan_on_error() to dump the test logs in
the same way it happens in the custom SIGSEGV handler.

[1] https://lore.kernel.org/bpf/73d832948b01dbc0ebc60d85574bdf8537f3a810.camel@gmail.com/

Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/test_progs.c | 36 +++++++++++++++++-------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index d1418ec1f351..0929f4a7bda4 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1261,14 +1261,8 @@ int get_bpf_max_tramp_links(void)
 	return ret;
 }
 
-#define MAX_BACKTRACE_SZ 128
-void crash_handler(int signum)
+static void dump_crash_log(void)
 {
-	void *bt[MAX_BACKTRACE_SZ];
-	size_t sz;
-
-	sz = backtrace(bt, ARRAY_SIZE(bt));
-
 	fflush(stdout);
 	stdout = env.stdout_saved;
 	stderr = env.stderr_saved;
@@ -1277,12 +1271,32 @@ void crash_handler(int signum)
 		env.test_state->error_cnt++;
 		dump_test_log(env.test, env.test_state, true, false, NULL);
 	}
+}
+
+#define MAX_BACKTRACE_SZ 128
+
+void crash_handler(int signum)
+{
+	void *bt[MAX_BACKTRACE_SZ];
+	size_t sz;
+
+	sz = backtrace(bt, ARRAY_SIZE(bt));
+
+	dump_crash_log();
+
 	if (env.worker_id != -1)
 		fprintf(stderr, "[%d]: ", env.worker_id);
 	fprintf(stderr, "Caught signal #%d!\nStack trace:\n", signum);
 	backtrace_symbols_fd(bt, sz, STDERR_FILENO);
 }
 
+#ifdef __SANITIZE_ADDRESS__
+void __asan_on_error(void)
+{
+	dump_crash_log();
+}
+#endif
+
 void hexdump(const char *prefix, const void *buf, size_t len)
 {
 	for (int i = 0; i < len; i++) {
@@ -1944,13 +1958,15 @@ int main(int argc, char **argv)
 		.parser = parse_arg,
 		.doc = argp_program_doc,
 	};
+	int err, i;
+
+#ifndef __SANITIZE_ADDRESS__
 	struct sigaction sigact = {
 		.sa_handler = crash_handler,
 		.sa_flags = SA_RESETHAND,
-		};
-	int err, i;
-
+	};
 	sigaction(SIGSEGV, &sigact, NULL);
+#endif
 
 	env.stdout_saved = stdout;
 	env.stderr_saved = stderr;
-- 
2.53.0


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

* Re: [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() with strscpy()
  2026-02-23 19:07 ` [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() " Ihor Solodrai
@ 2026-02-23 22:28   ` Eduard Zingerman
  2026-02-23 22:32     ` Ihor Solodrai
  0 siblings, 1 reply; 26+ messages in thread
From: Eduard Zingerman @ 2026-02-23 22:28 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

On Mon, 2026-02-23 at 11:07 -0800, Ihor Solodrai wrote:

[...]

> diff --git a/tools/testing/selftests/bpf/prog_tests/align.c b/tools/testing/selftests/bpf/prog_tests/align.c
> index 24c509ce4e5b..841a166b8081 100644
> --- a/tools/testing/selftests/bpf/prog_tests/align.c
> +++ b/tools/testing/selftests/bpf/prog_tests/align.c
> @@ -633,7 +633,7 @@ static int do_test_single(struct bpf_align_test *test)
>  	} else {
>  		ret = 0;
>  		/* We make a local copy so that we can strtok() it */
> -		strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
> +		strscpy(bpf_vlog_copy, bpf_vlog);
>  		start = strstr(bpf_vlog_copy, main_pass_start);
>  		if (!start) {
>  			ret = 1;

This hunk no longer applies.

[...]

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

* Re: [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() with strscpy()
  2026-02-23 22:28   ` Eduard Zingerman
@ 2026-02-23 22:32     ` Ihor Solodrai
  2026-02-23 22:59       ` Eduard Zingerman
  0 siblings, 1 reply; 26+ messages in thread
From: Ihor Solodrai @ 2026-02-23 22:32 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

On 2/23/26 2:28 PM, Eduard Zingerman wrote:
> On Mon, 2026-02-23 at 11:07 -0800, Ihor Solodrai wrote:
> 
> [...]
> 
>> diff --git a/tools/testing/selftests/bpf/prog_tests/align.c b/tools/testing/selftests/bpf/prog_tests/align.c
>> index 24c509ce4e5b..841a166b8081 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/align.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/align.c
>> @@ -633,7 +633,7 @@ static int do_test_single(struct bpf_align_test *test)
>>  	} else {
>>  		ret = 0;
>>  		/* We make a local copy so that we can strtok() it */
>> -		strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
>> +		strscpy(bpf_vlog_copy, bpf_vlog);
>>  		start = strstr(bpf_vlog_copy, main_pass_start);
>>  		if (!start) {
>>  			ret = 1;
> 
> This hunk no longer applies.


Hmm... Applies for me. What revision did you try?

$ git log -1 --oneline 
6de23f81a5e0 (HEAD, tag: v7.0-rc1, origin/bpf) Linux 7.0-rc1

$ b4 shazam 20260223190736.649171-1-ihor.solodrai@linux.dev
Grabbing thread from lore.kernel.org/all/20260223190736.649171-1-ihor.solodrai@linux.dev/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Analyzing 22 messages in the thread
Looking for additional code-review trailers on lore.kernel.org
Analyzing 103 code-review messages
Checking attestation on all messages, may take a moment...
---
  ✓ [PATCH v4 1/20] selftests/bpf: Add simple strscpy() implementation
  ✓ [PATCH v4 2/20] selftests/bpf: Replace strcpy() calls with strscpy()
  ✓ [PATCH v4 3/20] selftests/bpf: Replace strncpy() with strscpy()
  ✓ [PATCH v4 4/20] selftests/bpf: Use strscpy in bpftool_helpers.c
  ✓ [PATCH v4 5/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies
  ✓ [PATCH v4 6/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
  ✓ [PATCH v4 7/20] resolve_btfids: Fix memory leaks reported by ASAN
  ✓ [PATCH v4 8/20] selftests/bpf: Add DENYLIST.asan
  ✓ [PATCH v4 9/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper
  ✓ [PATCH v4 10/20] selftests/bpf: Fix memory leaks in tests
  ✓ [PATCH v4 11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
  ✓ [PATCH v4 12/20] veristat: Fix a memory leak for preset ENUMERATOR
  ✓ [PATCH v4 13/20] selftests/bpf: Fix use-after-free in xdp_metadata test
  ✓ [PATCH v4 14/20] selftests/bpf: Fix double thread join in uprobe_multi_test
  ✓ [PATCH v4 15/20] selftests/bpf: Fix resource leaks caused by missing cleanups
  ✓ [PATCH v4 16/20] selftests/bpf: Free bpf_object in test_sysctl
  ✓ [PATCH v4 17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers
  ✓ [PATCH v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
  ✓ [PATCH v4 19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
  ✓ [PATCH v4 20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN
  ---
  ✓ Signed: DKIM/linux.dev
---
Total patches: 20
---
Applying: selftests/bpf: Add simple strscpy() implementation
Applying: selftests/bpf: Replace strcpy() calls with strscpy()
Applying: selftests/bpf: Replace strncpy() with strscpy()
Applying: selftests/bpf: Use strscpy in bpftool_helpers.c
Applying: selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies
Applying: selftests/bpf: Pass through build flags to bpftool and resolve_btfids
Applying: resolve_btfids: Fix memory leaks reported by ASAN
Applying: selftests/bpf: Add DENYLIST.asan
Applying: selftests/bpf: Refactor bpf_get_ksyms() trace helper
Applying: selftests/bpf: Fix memory leaks in tests
Applying: selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
Applying: veristat: Fix a memory leak for preset ENUMERATOR
Applying: selftests/bpf: Fix use-after-free in xdp_metadata test
Applying: selftests/bpf: Fix double thread join in uprobe_multi_test
Applying: selftests/bpf: Fix resource leaks caused by missing cleanups
Applying: selftests/bpf: Free bpf_object in test_sysctl
Applying: selftests/bpf: Fix array bounds warning in jit_disasm_helpers
Applying: selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
Applying: selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
Applying: selftests/bpf: Don't override SIGSEGV handler with ASAN


> 
> [...]


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

* Re: [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() with strscpy()
  2026-02-23 22:32     ` Ihor Solodrai
@ 2026-02-23 22:59       ` Eduard Zingerman
  0 siblings, 0 replies; 26+ messages in thread
From: Eduard Zingerman @ 2026-02-23 22:59 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

On Mon, 2026-02-23 at 14:32 -0800, Ihor Solodrai wrote:
> On 2/23/26 2:28 PM, Eduard Zingerman wrote:
> > On Mon, 2026-02-23 at 11:07 -0800, Ihor Solodrai wrote:
> > 
> > [...]
> > 
> > > diff --git a/tools/testing/selftests/bpf/prog_tests/align.c b/tools/testing/selftests/bpf/prog_tests/align.c
> > > index 24c509ce4e5b..841a166b8081 100644
> > > --- a/tools/testing/selftests/bpf/prog_tests/align.c
> > > +++ b/tools/testing/selftests/bpf/prog_tests/align.c
> > > @@ -633,7 +633,7 @@ static int do_test_single(struct bpf_align_test *test)
> > >  	} else {
> > >  		ret = 0;
> > >  		/* We make a local copy so that we can strtok() it */
> > > -		strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
> > > +		strscpy(bpf_vlog_copy, bpf_vlog);
> > >  		start = strstr(bpf_vlog_copy, main_pass_start);
> > >  		if (!start) {
> > >  			ret = 1;
> > 
> > This hunk no longer applies.
> 
> 
> Hmm... Applies for me. What revision did you try?
> 
> $ git log -1 --oneline 
> 6de23f81a5e0 (HEAD, tag: v7.0-rc1, origin/bpf) Linux 7.0-rc1
> 
> $ b4 shazam 20260223190736.649171-1-ihor.solodrai@linux.dev
> Grabbing thread from lore.kernel.org/all/20260223190736.649171-1-ihor.solodrai@linux.dev/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Analyzing 22 messages in the thread
> Looking for additional code-review trailers on lore.kernel.org
> Analyzing 103 code-review messages
> Checking attestation on all messages, may take a moment...
> ---

Uh-oh, it is for 'bpf' tree. I applied to 'bpf-next', sorry for the noise.

[...]

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

* Re: [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper
  2026-02-23 19:07 ` [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
@ 2026-02-23 23:23   ` Eduard Zingerman
  0 siblings, 0 replies; 26+ messages in thread
From: Eduard Zingerman @ 2026-02-23 23:23 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Jiri Olsa, Mykyta Yatsenko, Alexis Lothoré
  Cc: Amery Hung, bpf, linux-kernel, kernel-team

On Mon, 2026-02-23 at 11:07 -0800, Ihor Solodrai wrote:
> ASAN reported a memory leak in bpf_get_ksyms(): it allocates a struct
> ksyms internally and never frees it.
> 
> Move struct ksyms to trace_helpers.h and return it from the
> bpf_get_ksyms(), giving ownership to the caller. Add filtered_syms and
> filtered_cnt fields to the ksyms to hold the filtered array of
> symbols, previously returned by bpf_get_ksyms().
> 
> Fixup the call sites: kprobe_multi_test and bench_trigger.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

[...]

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

* Re: [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN
  2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
                   ` (17 preceding siblings ...)
  2026-02-23 19:11 ` [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
@ 2026-02-24  3:00 ` patchwork-bot+netdevbpf
  18 siblings, 0 replies; 26+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-02-24  3:00 UTC (permalink / raw)
  To: Ihor Solodrai
  Cc: ast, andrii, daniel, eddyz87, olsajiri, yatsenko, alexis.lothore,
	ameryhung, bpf, linux-kernel, kernel-team

Hello:

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

On Mon, 23 Feb 2026 11:07:16 -0800 you wrote:
> This series includes various fixes aiming to enable test_progs run
> with userspace address sanitizer on BPF CI.
> 
> The first five patches add a simplified implementation of strscpy() to
> selftests/bpf and then replace strcpy/strncpy usages across the tests
> with it. See relevant discussions [1][2].
> 
> [...]

Here is the summary with links:
  - [bpf,v4,01/20] selftests/bpf: Add simple strscpy() implementation
    https://git.kernel.org/bpf/bpf/c/63c49efc987a
  - [bpf,v4,02/20] selftests/bpf: Replace strcpy() calls with strscpy()
    https://git.kernel.org/bpf/bpf/c/6a087ac23f5b
  - [bpf,v4,03/20] selftests/bpf: Replace strncpy() with strscpy()
    https://git.kernel.org/bpf/bpf/c/05849ec34f3d
  - [bpf,v4,04/20] selftests/bpf: Use strscpy in bpftool_helpers.c
    https://git.kernel.org/bpf/bpf/c/f074d8941c29
  - [bpf,v4,05/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies
    https://git.kernel.org/bpf/bpf/c/6fcf7925e334
  - [bpf,v4,06/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
    https://git.kernel.org/bpf/bpf/c/b1dc4f39b541
  - [bpf,v4,07/20] resolve_btfids: Fix memory leaks reported by ASAN
    https://git.kernel.org/bpf/bpf/c/08a4ab51771f
  - [bpf,v4,08/20] selftests/bpf: Add DENYLIST.asan
    https://git.kernel.org/bpf/bpf/c/7661538bb7d2
  - [bpf,v4,09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper
    https://git.kernel.org/bpf/bpf/c/536abce60307
  - [bpf,v4,10/20] selftests/bpf: Fix memory leaks in tests
    https://git.kernel.org/bpf/bpf/c/f8e7eccf33d3
  - [bpf,v4,11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
    https://git.kernel.org/bpf/bpf/c/e4093ebf3db1
  - [bpf,v4,12/20] veristat: Fix a memory leak for preset ENUMERATOR
    https://git.kernel.org/bpf/bpf/c/10d19e708d3b
  - [bpf,v4,13/20] selftests/bpf: Fix use-after-free in xdp_metadata test
    https://git.kernel.org/bpf/bpf/c/4650dd3ea4ac
  - [bpf,v4,14/20] selftests/bpf: Fix double thread join in uprobe_multi_test
    https://git.kernel.org/bpf/bpf/c/a9b15811ef10
  - [bpf,v4,15/20] selftests/bpf: Fix resource leaks caused by missing cleanups
    https://git.kernel.org/bpf/bpf/c/547a83e93a48
  - [bpf,v4,16/20] selftests/bpf: Free bpf_object in test_sysctl
    https://git.kernel.org/bpf/bpf/c/1907d7a6ca0f
  - [bpf,v4,17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers
    https://git.kernel.org/bpf/bpf/c/68da3afd0bf0
  - [bpf,v4,18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
    https://git.kernel.org/bpf/bpf/c/a3f40c2890e9
  - [bpf,v4,19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
    https://git.kernel.org/bpf/bpf/c/fe9f7aa74767
  - [bpf,v4,20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN
    https://git.kernel.org/bpf/bpf/c/db7337948c7b

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] 26+ messages in thread

end of thread, other threads:[~2026-02-24  3:00 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-23 19:07 [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 01/20] selftests/bpf: Add simple strscpy() implementation Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 02/20] selftests/bpf: Replace strcpy() calls with strscpy() Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 03/20] selftests/bpf: Replace strncpy() " Ihor Solodrai
2026-02-23 22:28   ` Eduard Zingerman
2026-02-23 22:32     ` Ihor Solodrai
2026-02-23 22:59       ` Eduard Zingerman
2026-02-23 19:07 ` [PATCH bpf v4 04/20] selftests/bpf: Use strscpy in bpftool_helpers.c Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 05/20] selftests/bpf: Use memcpy() for bounded non-NULL-terminated copies Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 06/20] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 07/20] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 08/20] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 09/20] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
2026-02-23 23:23   ` Eduard Zingerman
2026-02-23 19:07 ` [PATCH bpf v4 10/20] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 11/20] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 12/20] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 13/20] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 14/20] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 15/20] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 16/20] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
2026-02-23 19:07 ` [PATCH bpf v4 17/20] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
2026-02-23 19:11 ` [PATCH bpf v4 18/20] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
2026-02-23 19:11   ` [PATCH bpf v4 19/20] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
2026-02-23 19:11   ` [PATCH bpf v4 20/20] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
2026-02-24  3:00 ` [PATCH bpf v4 00/20] selftests/bpf: Fixes for userspace ASAN 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