* [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:57 ` bot+bpf-ci
2026-02-20 22:25 ` [PATCH bpf v3 02/15] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
` (13 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-02-20 22:25 ` [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
@ 2026-02-20 22:57 ` bot+bpf-ci
2026-02-21 4:23 ` Ihor Solodrai
0 siblings, 1 reply; 24+ messages in thread
From: bot+bpf-ci @ 2026-02-20 22:57 UTC (permalink / raw)
To: ihor.solodrai, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore
Cc: ameryhung, bpf, linux-kernel, kernel-team, ast, andrii, daniel,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2174 bytes --]
> 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)
The "|| echo -lzstd" fallback makes zstd an unconditional link
dependency. On systems where libzstd-dev is not installed, pkg-config
fails and the fallback provides -lzstd, but the linker cannot find the
library and the build fails.
bpftool handles the same transitive dependency conditionally via a
feature test:
tools/bpf/bpftool/Makefile:
ifeq ($(feature-libelf-zstd),1)
LIBS += -lzstd
LIBS_BOOTSTRAP += -lzstd
endif
Would it be safer to drop the fallback here so ZSTD_LIBS is empty
when zstd is not available?
ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
This would still link zstd when present (needed for the static linking
case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
avoid breaking dynamic builds on systems without libzstd-dev.
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22243753316
AI-authorship-score: low
AI-authorship-explanation: Human-characteristic typo in commit message, natural lore discussion with incremental debugging, and standard Makefile pattern reuse all indicate human authorship.
issues-found: 1
issue-severity-score: low
issue-severity-explanation: Unconditional zstd link fallback in resolve_btfids Makefile can break builds on systems without libzstd-dev, but the affected scenario is narrow and limited to the selftests build system.
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-02-20 22:57 ` bot+bpf-ci
@ 2026-02-21 4:23 ` Ihor Solodrai
2026-03-02 15:22 ` Vitaly Chikunov
0 siblings, 1 reply; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-21 4:23 UTC (permalink / raw)
To: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore
Cc: ameryhung, bpf, linux-kernel, kernel-team, martin.lau,
yonghong.song, clm
On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
>> 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)
>
> The "|| echo -lzstd" fallback makes zstd an unconditional link
> dependency. On systems where libzstd-dev is not installed, pkg-config
> fails and the fallback provides -lzstd, but the linker cannot find the
> library and the build fails.
>
> bpftool handles the same transitive dependency conditionally via a
> feature test:
>
> tools/bpf/bpftool/Makefile:
> ifeq ($(feature-libelf-zstd),1)
> LIBS += -lzstd
> LIBS_BOOTSTRAP += -lzstd
> endif
>
> Would it be safer to drop the fallback here so ZSTD_LIBS is empty
> when zstd is not available?
>
> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
>
> This would still link zstd when present (needed for the static linking
> case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
> avoid breaking dynamic builds on systems without libzstd-dev.
I tried to reproduce the situation like follows:
$ git remote -v
origin git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git (fetch)
origin git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git (push)
$ git log --oneline -n1
8bf22c33e7a1 (HEAD -> master, origin/master, origin/HEAD) Merge tag 'net-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
$ b4 shazam 20260220182011.802116-1-ihor.solodrai@linux.dev # apply strscpy series
$ b4 shazam 20260220222604.1155148-1-ihor.solodrai@linux.dev # apply ASAN series
$ podman pull debian:latest
$ podman run -it --rm -v $(pwd):/linux debian:latest /bin/bash
# in the container
$ apt update -y && apt install -y make gcc python3 libelf-dev
# note: no libzstd-dev
$ cd /linux/tools/bpf/resolve_btfids/
$ make -j8
# build is successful
$ ldd resolve_btfids
linux-vdso.so.1 (0x00007f3eecc81000)
libelf.so.1 => /lib/x86_64-linux-gnu/libelf.so.1 (0x00007f3eecbe2000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f3eecbc2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3eec9cd000)
libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f3eec903000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3eecc83000)
So, while AI may be technically correct that the build will fail if
libelf is installed and libzstd is not, it seems a far-fetched
situation, given that libelf depends on libzstd.
I think we can leave the default -lzstd to have an explicit
dependency in the Makefile.
>
> [ ... ]
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22243753316
>
> AI-authorship-score: low
> AI-authorship-explanation: Human-characteristic typo in commit message, natural lore discussion with incremental debugging, and standard Makefile pattern reuse all indicate human authorship.
> issues-found: 1
> issue-severity-score: low
> issue-severity-explanation: Unconditional zstd link fallback in resolve_btfids Makefile can break builds on systems without libzstd-dev, but the affected scenario is narrow and limited to the selftests build system.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-02-21 4:23 ` Ihor Solodrai
@ 2026-03-02 15:22 ` Vitaly Chikunov
2026-03-02 18:01 ` Ihor Solodrai
0 siblings, 1 reply; 24+ messages in thread
From: Vitaly Chikunov @ 2026-03-02 15:22 UTC (permalink / raw)
To: Ihor Solodrai
Cc: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore, ameryhung, bpf, linux-kernel, kernel-team,
martin.lau, yonghong.song, clm
Ihor,
On Fri, Feb 20, 2026 at 08:23:51PM -0800, Ihor Solodrai wrote:
>
>
> On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
> >> 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)
> >
> > The "|| echo -lzstd" fallback makes zstd an unconditional link
> > dependency. On systems where libzstd-dev is not installed, pkg-config
> > fails and the fallback provides -lzstd, but the linker cannot find the
> > library and the build fails.
> >
> > bpftool handles the same transitive dependency conditionally via a
> > feature test:
> >
> > tools/bpf/bpftool/Makefile:
> > ifeq ($(feature-libelf-zstd),1)
> > LIBS += -lzstd
> > LIBS_BOOTSTRAP += -lzstd
> > endif
> >
> > Would it be safer to drop the fallback here so ZSTD_LIBS is empty
> > when zstd is not available?
> >
> > ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
> >
> > This would still link zstd when present (needed for the static linking
> > case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
> > avoid breaking dynamic builds on systems without libzstd-dev.
>
> I tried to reproduce the situation like follows:
>
> $ git remote -v
> origin git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git (fetch)
> origin git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git (push)
>
> $ git log --oneline -n1
> 8bf22c33e7a1 (HEAD -> master, origin/master, origin/HEAD) Merge tag 'net-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
>
> $ b4 shazam 20260220182011.802116-1-ihor.solodrai@linux.dev # apply strscpy series
> $ b4 shazam 20260220222604.1155148-1-ihor.solodrai@linux.dev # apply ASAN series
>
> $ podman pull debian:latest
> $ podman run -it --rm -v $(pwd):/linux debian:latest /bin/bash
>
> # in the container
> $ apt update -y && apt install -y make gcc python3 libelf-dev
> # note: no libzstd-dev
>
> $ cd /linux/tools/bpf/resolve_btfids/
> $ make -j8
> # build is successful
>
> $ ldd resolve_btfids
> linux-vdso.so.1 (0x00007f3eecc81000)
> libelf.so.1 => /lib/x86_64-linux-gnu/libelf.so.1 (0x00007f3eecbe2000)
> libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f3eecbc2000)
> libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3eec9cd000)
> libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f3eec903000)
> /lib64/ld-linux-x86-64.so.2 (0x00007f3eecc83000)
>
>
> So, while AI may be technically correct that the build will fail if
> libelf is installed and libzstd is not, it seems a far-fetched
> situation, given that libelf depends on libzstd.
This is not far-fetched, and we have build failure for v7.0-rc2 due to
this.
ld: cannot find -lzstd: No such file or directory
Even though libelf is linked with libzstd, this does not imply
libzstd-devel (with headers and so library) is there when building.
Thanks,
>
> I think we can leave the default -lzstd to have an explicit
> dependency in the Makefile.
>
>
> >
> > [ ... ]
> >
> >
> > ---
> > AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> > See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> >
> > CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22243753316
> >
> > AI-authorship-score: low
> > AI-authorship-explanation: Human-characteristic typo in commit message, natural lore discussion with incremental debugging, and standard Makefile pattern reuse all indicate human authorship.
> > issues-found: 1
> > issue-severity-score: low
> > issue-severity-explanation: Unconditional zstd link fallback in resolve_btfids Makefile can break builds on systems without libzstd-dev, but the affected scenario is narrow and limited to the selftests build system.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-03-02 15:22 ` Vitaly Chikunov
@ 2026-03-02 18:01 ` Ihor Solodrai
2026-03-02 20:27 ` Vitaly Chikunov
0 siblings, 1 reply; 24+ messages in thread
From: Ihor Solodrai @ 2026-03-02 18:01 UTC (permalink / raw)
To: Vitaly Chikunov
Cc: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore, ameryhung, bpf, linux-kernel, kernel-team,
martin.lau, yonghong.song, clm
On 3/2/26 7:22 AM, Vitaly Chikunov wrote:
> Ihor,
>
> On Fri, Feb 20, 2026 at 08:23:51PM -0800, Ihor Solodrai wrote:
>>
>>
>> On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
>>>> 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)
>>>
>>> The "|| echo -lzstd" fallback makes zstd an unconditional link
>>> dependency. On systems where libzstd-dev is not installed, pkg-config
>>> fails and the fallback provides -lzstd, but the linker cannot find the
>>> library and the build fails.
>>>
>>> bpftool handles the same transitive dependency conditionally via a
>>> feature test:
>>>
>>> tools/bpf/bpftool/Makefile:
>>> ifeq ($(feature-libelf-zstd),1)
>>> LIBS += -lzstd
>>> LIBS_BOOTSTRAP += -lzstd
>>> endif
>>>
>>> Would it be safer to drop the fallback here so ZSTD_LIBS is empty
>>> when zstd is not available?
>>>
>>> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
>>>
>>> This would still link zstd when present (needed for the static linking
>>> case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
>>> avoid breaking dynamic builds on systems without libzstd-dev.
>>
>> [...]
>>
>>
>> So, while AI may be technically correct that the build will fail if
>> libelf is installed and libzstd is not, it seems a far-fetched
>> situation, given that libelf depends on libzstd.
>
> This is not far-fetched, and we have build failure for v7.0-rc2 due to
> this.
>
> ld: cannot find -lzstd: No such file or directory
>
> Even though libelf is linked with libzstd, this does not imply
> libzstd-devel (with headers and so library) is there when building.
Does AI's suggestion make sense in your case then?
That is, make ZSTD_LIBS empty in case pkg-config didn't find libzstd?
I'm happy to fix this, the build shouldn't fail unless it must.
But I am curious how and why an environment building Linux with BTF
(requiring build and run of resolve_btfids), which needs libelf-dev
and presumably its dependencies, would exclude/avoid installing
libzstd-dev?
Thanks.
>
> Thanks,
>
>>
>> I think we can leave the default -lzstd to have an explicit
>> dependency in the Makefile.
>>
>>
>>>
>>> [ ... ]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-03-02 18:01 ` Ihor Solodrai
@ 2026-03-02 20:27 ` Vitaly Chikunov
2026-03-02 22:42 ` Ihor Solodrai
0 siblings, 1 reply; 24+ messages in thread
From: Vitaly Chikunov @ 2026-03-02 20:27 UTC (permalink / raw)
To: Ihor Solodrai
Cc: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore, ameryhung, bpf, linux-kernel, kernel-team,
martin.lau, yonghong.song, clm
Ihor,
On Mon, Mar 02, 2026 at 10:01:59AM -0800, Ihor Solodrai wrote:
> On 3/2/26 7:22 AM, Vitaly Chikunov wrote:
> > On Fri, Feb 20, 2026 at 08:23:51PM -0800, Ihor Solodrai wrote:
> >> On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
> >>>> 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)
> >>>
> >>> The "|| echo -lzstd" fallback makes zstd an unconditional link
> >>> dependency. On systems where libzstd-dev is not installed, pkg-config
> >>> fails and the fallback provides -lzstd, but the linker cannot find the
> >>> library and the build fails.
> >>>
> >>> bpftool handles the same transitive dependency conditionally via a
> >>> feature test:
> >>>
> >>> tools/bpf/bpftool/Makefile:
> >>> ifeq ($(feature-libelf-zstd),1)
> >>> LIBS += -lzstd
> >>> LIBS_BOOTSTRAP += -lzstd
> >>> endif
> >>>
> >>> Would it be safer to drop the fallback here so ZSTD_LIBS is empty
> >>> when zstd is not available?
> >>>
> >>> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
> >>>
> >>> This would still link zstd when present (needed for the static linking
> >>> case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
> >>> avoid breaking dynamic builds on systems without libzstd-dev.
> >>
> >> [...]
> >>
> >>
> >> So, while AI may be technically correct that the build will fail if
> >> libelf is installed and libzstd is not, it seems a far-fetched
> >> situation, given that libelf depends on libzstd.
> >
> > This is not far-fetched, and we have build failure for v7.0-rc2 due to
> > this.
> >
> > ld: cannot find -lzstd: No such file or directory
> >
> > Even though libelf is linked with libzstd, this does not imply
> > libzstd-devel (with headers and so library) is there when building.
>
> Does AI's suggestion make sense in your case then?
> That is, make ZSTD_LIBS empty in case pkg-config didn't find libzstd?
>
> I'm happy to fix this, the build shouldn't fail unless it must.
>
> But I am curious how and why an environment building Linux with BTF
> (requiring build and run of resolve_btfids), which needs libelf-dev
> and presumably its dependencies, would exclude/avoid installing
> libzstd-dev?
Are you providing -lzstd just to link with libelf? I don't think you need to
care about zstd in that case. libelf is already linked with libzstd. If you
don't use libzstd functions yourself you don't need to link with -lzstd.
Example build without -lzstd:
builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ grep zstd tools/bpf/resolve_btfids/Makefile
ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ ldd ./tools/bpf/resolve_btfids/resolve_btfids
linux-vdso.so.1 (0x00007ff8b2329000)
libelf.so.1 => /lib64/libelf.so.1 (0x00007ff8b2287000)
libz.so.1 => /lib64/libz.so.1 (0x00007ff8b2269000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff8b206e000)
libzstd.so.1 => /lib64/libzstd.so.1 (0x00007ff8b1fc8000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff8b232b000)
builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd
libzstd-1.5.5-alt2.x86_64
builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd-devel
package libzstd-devel is not installed
lib*-devel/-dev packages only required if your source is directly using the
target lib, in other causes this is already handled.
Thanks,
>
> Thanks.
>
> >
> > Thanks,
> >
> >>
> >> I think we can leave the default -lzstd to have an explicit
> >> dependency in the Makefile.
> >>
> >>
> >>>
> >>> [ ... ]
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-03-02 20:27 ` Vitaly Chikunov
@ 2026-03-02 22:42 ` Ihor Solodrai
2026-03-03 4:01 ` Vitaly Chikunov
0 siblings, 1 reply; 24+ messages in thread
From: Ihor Solodrai @ 2026-03-02 22:42 UTC (permalink / raw)
To: Vitaly Chikunov
Cc: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore, ameryhung, bpf, linux-kernel, kernel-team,
martin.lau, yonghong.song, clm
On 3/2/26 12:27 PM, Vitaly Chikunov wrote:
> Ihor,
>
> On Mon, Mar 02, 2026 at 10:01:59AM -0800, Ihor Solodrai wrote:
>> On 3/2/26 7:22 AM, Vitaly Chikunov wrote:
>>> On Fri, Feb 20, 2026 at 08:23:51PM -0800, Ihor Solodrai wrote:
>>>> On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
>>>>>> 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)
>>>>>
>>>>> The "|| echo -lzstd" fallback makes zstd an unconditional link
>>>>> dependency. On systems where libzstd-dev is not installed, pkg-config
>>>>> fails and the fallback provides -lzstd, but the linker cannot find the
>>>>> library and the build fails.
>>>>>
>>>>> bpftool handles the same transitive dependency conditionally via a
>>>>> feature test:
>>>>>
>>>>> tools/bpf/bpftool/Makefile:
>>>>> ifeq ($(feature-libelf-zstd),1)
>>>>> LIBS += -lzstd
>>>>> LIBS_BOOTSTRAP += -lzstd
>>>>> endif
>>>>>
>>>>> Would it be safer to drop the fallback here so ZSTD_LIBS is empty
>>>>> when zstd is not available?
>>>>>
>>>>> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
>>>>>
>>>>> This would still link zstd when present (needed for the static linking
>>>>> case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
>>>>> avoid breaking dynamic builds on systems without libzstd-dev.
>>>>
>>>> [...]
>>>>
>>>>
>>>> So, while AI may be technically correct that the build will fail if
>>>> libelf is installed and libzstd is not, it seems a far-fetched
>>>> situation, given that libelf depends on libzstd.
>>>
>>> This is not far-fetched, and we have build failure for v7.0-rc2 due to
>>> this.
>>>
>>> ld: cannot find -lzstd: No such file or directory
>>>
>>> Even though libelf is linked with libzstd, this does not imply
>>> libzstd-devel (with headers and so library) is there when building.
>>
>> Does AI's suggestion make sense in your case then?
>> That is, make ZSTD_LIBS empty in case pkg-config didn't find libzstd?
>>
>> I'm happy to fix this, the build shouldn't fail unless it must.
>>
>> But I am curious how and why an environment building Linux with BTF
>> (requiring build and run of resolve_btfids), which needs libelf-dev
>> and presumably its dependencies, would exclude/avoid installing
>> libzstd-dev?
>
> Are you providing -lzstd just to link with libelf? I don't think you need to
An explicit -lzstd flag was added to enable a static build [1].
> care about zstd in that case. libelf is already linked with libzstd. If you
> don't use libzstd functions yourself you don't need to link with -lzstd.
>
> Example build without -lzstd:
>
> builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ grep zstd tools/bpf/resolve_btfids/Makefile
> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
>
> builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ ldd ./tools/bpf/resolve_btfids/resolve_btfids
> linux-vdso.so.1 (0x00007ff8b2329000)
> libelf.so.1 => /lib64/libelf.so.1 (0x00007ff8b2287000)
> libz.so.1 => /lib64/libz.so.1 (0x00007ff8b2269000)
> libc.so.6 => /lib64/libc.so.6 (0x00007ff8b206e000)
> libzstd.so.1 => /lib64/libzstd.so.1 (0x00007ff8b1fc8000)
> /lib64/ld-linux-x86-64.so.2 (0x00007ff8b232b000)
> builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd
> libzstd-1.5.5-alt2.x86_64
> builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd-devel
> package libzstd-devel is not installed
>
> lib*-devel/-dev packages only required if your source is directly using the
> target lib, in other causes this is already handled.
The issue that AI has raised is whether to leave -lzstd link flag by
default or not. I decided to leave it on the assumption that the
environments building Linux with BTF (hence building and running
resovle_btfids) would have libelf-dev installed (because -lelf has
been a requirement forever [2]), and libzstd-dev is its dependency.
I checked a few recent distros, all of them have libzstd-dev as a
direct dependency of libelf-dev, which supports my assumption:
# Fedora
$ dnf repoquery --providers-of=depends elfutils-libelf-devel
Updating and loading repositories:
Repositories loaded.
elfutils-libelf-0:0.194-1.fc43.i686
elfutils-libelf-0:0.194-1.fc43.x86_64
libzstd-devel-0:1.5.7-2.fc43.i686
libzstd-devel-0:1.5.7-2.fc43.x86_64
pkgconf-pkg-config-0:2.3.0-3.fc43.i686
pkgconf-pkg-config-0:2.3.0-3.fc43.x86_64
zlib-ng-compat-devel-0:2.3.3-1.fc43.i686
zlib-ng-compat-devel-0:2.3.3-1.fc43.x86_64
# Ubuntu
$ apt info libelf-dev
Package: libelf-dev
Version: 0.190-1.1ubuntu0.1
Priority: optional
Section: libdevel
Source: elfutils
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Elfutils Maintainers <debian-gcc@lists.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 385 kB
Depends: libelf1t64 (= 0.190-1.1ubuntu0.1), zlib1g-dev, libzstd-dev
Conflicts: libelfg0-dev
[...]
# Debian
$ apt info libelf-dev
Package: libelf-dev
Version: 0.192-4
Priority: optional
Section: libdevel
Source: elfutils
Maintainer: Debian Elfutils Maintainers <debian-gcc@lists.debian.org>
Installed-Size: 420 kB
Depends: libelf1t64 (= 0.192-4), zlib1g-dev, libzstd-dev
Conflicts: libelfg0-dev
[...]
Of course it's plausible to have a system where libelf-dev is present
while libzstd-dev is not, as demonstrated by you running one.
Anyways this is easy to fix, I'll send a patch shortly.
[1] https://lore.kernel.org/bpf/4ff82800-2daa-4b9f-95a9-6f512859ee70@linux.dev/
[2] https://lore.kernel.org/bpf/20200711215329.41165-2-jolsa@kernel.org/
>
> Thanks,
>
>>
>> Thanks.
>>
>>>
>>> Thanks,
>>>
>>>>
>>>> I think we can leave the default -lzstd to have an explicit
>>>> dependency in the Makefile.
>>>>
>>>>
>>>>>
>>>>> [ ... ]
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids
2026-03-02 22:42 ` Ihor Solodrai
@ 2026-03-03 4:01 ` Vitaly Chikunov
0 siblings, 0 replies; 24+ messages in thread
From: Vitaly Chikunov @ 2026-03-03 4:01 UTC (permalink / raw)
To: Ihor Solodrai
Cc: bot+bpf-ci, ast, andrii, daniel, eddyz87, olsajiri, yatsenko,
alexis.lothore, ameryhung, bpf, linux-kernel, kernel-team,
martin.lau, yonghong.song, clm
Ihor,
On Mon, Mar 02, 2026 at 02:42:11PM -0800, Ihor Solodrai wrote:
> On 3/2/26 12:27 PM, Vitaly Chikunov wrote:
> > On Mon, Mar 02, 2026 at 10:01:59AM -0800, Ihor Solodrai wrote:
> >> On 3/2/26 7:22 AM, Vitaly Chikunov wrote:
> >>> On Fri, Feb 20, 2026 at 08:23:51PM -0800, Ihor Solodrai wrote:
> >>>> On 2/20/26 2:57 PM, bot+bpf-ci@kernel.org wrote:
> >>>>>> 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)
> >>>>>
> >>>>> The "|| echo -lzstd" fallback makes zstd an unconditional link
> >>>>> dependency. On systems where libzstd-dev is not installed, pkg-config
> >>>>> fails and the fallback provides -lzstd, but the linker cannot find the
> >>>>> library and the build fails.
> >>>>>
> >>>>> bpftool handles the same transitive dependency conditionally via a
> >>>>> feature test:
> >>>>>
> >>>>> tools/bpf/bpftool/Makefile:
> >>>>> ifeq ($(feature-libelf-zstd),1)
> >>>>> LIBS += -lzstd
> >>>>> LIBS_BOOTSTRAP += -lzstd
> >>>>> endif
> >>>>>
> >>>>> Would it be safer to drop the fallback here so ZSTD_LIBS is empty
> >>>>> when zstd is not available?
> >>>>>
> >>>>> ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
> >>>>>
> >>>>> This would still link zstd when present (needed for the static linking
> >>>>> case where libelf.a pulls in ZSTD symbols from elf_compress.o), but
> >>>>> avoid breaking dynamic builds on systems without libzstd-dev.
> >>>>
> >>>> [...]
> >>>>
> >>>>
> >>>> So, while AI may be technically correct that the build will fail if
> >>>> libelf is installed and libzstd is not, it seems a far-fetched
> >>>> situation, given that libelf depends on libzstd.
> >>>
> >>> This is not far-fetched, and we have build failure for v7.0-rc2 due to
> >>> this.
> >>>
> >>> ld: cannot find -lzstd: No such file or directory
> >>>
> >>> Even though libelf is linked with libzstd, this does not imply
> >>> libzstd-devel (with headers and so library) is there when building.
> >>
> >> Does AI's suggestion make sense in your case then?
> >> That is, make ZSTD_LIBS empty in case pkg-config didn't find libzstd?
> >>
> >> I'm happy to fix this, the build shouldn't fail unless it must.
> >>
> >> But I am curious how and why an environment building Linux with BTF
> >> (requiring build and run of resolve_btfids), which needs libelf-dev
> >> and presumably its dependencies, would exclude/avoid installing
> >> libzstd-dev?
> >
> > Are you providing -lzstd just to link with libelf? I don't think you need to
>
> An explicit -lzstd flag was added to enable a static build [1].
>
> > care about zstd in that case. libelf is already linked with libzstd. If you
> > don't use libzstd functions yourself you don't need to link with -lzstd.
> >
> > Example build without -lzstd:
> >
> > builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ grep zstd tools/bpf/resolve_btfids/Makefile
> > ZSTD_LIBS := $(shell $(HOSTPKG_CONFIG) libzstd --libs 2>/dev/null)
> >
> > builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ ldd ./tools/bpf/resolve_btfids/resolve_btfids
> > linux-vdso.so.1 (0x00007ff8b2329000)
> > libelf.so.1 => /lib64/libelf.so.1 (0x00007ff8b2287000)
> > libz.so.1 => /lib64/libz.so.1 (0x00007ff8b2269000)
> > libc.so.6 => /lib64/libc.so.6 (0x00007ff8b206e000)
> > libzstd.so.1 => /lib64/libzstd.so.1 (0x00007ff8b1fc8000)
> > /lib64/ld-linux-x86-64.so.2 (0x00007ff8b232b000)
> > builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd
> > libzstd-1.5.5-alt2.x86_64
> > builder@x86_64:~/RPM/BUILD/kernel-image-7.0-rc2$ rpm -q libzstd-devel
> > package libzstd-devel is not installed
> >
> > lib*-devel/-dev packages only required if your source is directly using the
> > target lib, in other causes this is already handled.
>
> The issue that AI has raised is whether to leave -lzstd link flag by
> default or not. I decided to leave it on the assumption that the
> environments building Linux with BTF (hence building and running
> resovle_btfids) would have libelf-dev installed (because -lelf has
> been a requirement forever [2]), and libzstd-dev is its dependency.
>
> I checked a few recent distros, all of them have libzstd-dev as a
> direct dependency of libelf-dev, which supports my assumption:
>
> # Fedora
> $ dnf repoquery --providers-of=depends elfutils-libelf-devel
> Updating and loading repositories:
> Repositories loaded.
> elfutils-libelf-0:0.194-1.fc43.i686
> elfutils-libelf-0:0.194-1.fc43.x86_64
> libzstd-devel-0:1.5.7-2.fc43.i686
> libzstd-devel-0:1.5.7-2.fc43.x86_64
Interesting, but looks like this is not needed package dependency.
[fodora:rawhide@docker /]# grep zstd /usr/lib64/pkgconfig/libelf.pc
Requires.private: zlib libzstd
It's only a private dependency not exposed to the application.
pkg-config will not add -lzstd to link with libelf.so. (Unless it's
-static linking.) See pkg-config(1):
Requires.private:
A list of packages required by this package. The difference from Requires is
that the packages listed under Requires.private are not taken into account when
a flag list is computed for dynamically linked executable (i.e., when --static
was not specified). In the situation where each .pc file corresponds to a
library, Requires.private shall be used exclusively to specify the dependencies
between the libraries.
Perhaps, for your static linking case, you just need to extract -static from
EXTRA_LDFLAGS and add it to `pkg-config libelf --libs` to get the list of
static libraries to link with libelf, without defining ZSTD_LIBS at all.
This may provide other important flags besides these, see for example:
alt:sisyphus# pkg-config libelf --libs --static
-lelf -lz -lzstd -pthread
I think it's better to rely on pkg-config instead of guessing all the required
linking flags.
> pkgconf-pkg-config-0:2.3.0-3.fc43.i686
> pkgconf-pkg-config-0:2.3.0-3.fc43.x86_64
> zlib-ng-compat-devel-0:2.3.3-1.fc43.i686
> zlib-ng-compat-devel-0:2.3.3-1.fc43.x86_64
>
> # Ubuntu
> $ apt info libelf-dev
> Package: libelf-dev
> Version: 0.190-1.1ubuntu0.1
> Priority: optional
> Section: libdevel
> Source: elfutils
> Origin: Ubuntu
> Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
> Original-Maintainer: Debian Elfutils Maintainers <debian-gcc@lists.debian.org>
> Bugs: https://bugs.launchpad.net/ubuntu/+filebug
> Installed-Size: 385 kB
> Depends: libelf1t64 (= 0.190-1.1ubuntu0.1), zlib1g-dev, libzstd-dev
> Conflicts: libelfg0-dev
> [...]
>
> # Debian
> $ apt info libelf-dev
> Package: libelf-dev
> Version: 0.192-4
> Priority: optional
> Section: libdevel
> Source: elfutils
> Maintainer: Debian Elfutils Maintainers <debian-gcc@lists.debian.org>
> Installed-Size: 420 kB
> Depends: libelf1t64 (= 0.192-4), zlib1g-dev, libzstd-dev
> Conflicts: libelfg0-dev
> [...]
I don't know why these distros do this sort of dependency. In ALT Linux we
don't require libzstd-devel for linelf-devel, also, I just checked OpenMandriva
and it does not require this too. But, openSUSE requires libzstd-devel.
> Of course it's plausible to have a system where libelf-dev is present
> while libzstd-dev is not, as demonstrated by you running one.
>
> Anyways this is easy to fix, I'll send a patch shortly.
Thanks,
>
> [1] https://lore.kernel.org/bpf/4ff82800-2daa-4b9f-95a9-6f512859ee70@linux.dev/
> [2] https://lore.kernel.org/bpf/20200711215329.41165-2-jolsa@kernel.org/
>
>
> >
> > Thanks,
> >
> >>
> >> Thanks.
> >>
> >>>
> >>> Thanks,
> >>>
> >>>>
> >>>> I think we can leave the default -lzstd to have an explicit
> >>>> dependency in the Makefile.
> >>>>
> >>>>
> >>>>>
> >>>>> [ ... ]
> >>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH bpf v3 02/15] resolve_btfids: Fix memory leaks reported by ASAN
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 03/15] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
` (12 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 03/15] selftests/bpf: Add DENYLIST.asan
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 01/15] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 02/15] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 04/15] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
` (11 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 04/15] selftests/bpf: Refactor bpf_get_ksyms() trace helper
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (2 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 03/15] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 05/15] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
` (10 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 05/15] selftests/bpf: Fix memory leaks in tests
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (3 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 04/15] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 06/15] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
` (9 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 06/15] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big()
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (4 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 05/15] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 07/15] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
` (8 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 07/15] veristat: Fix a memory leak for preset ENUMERATOR
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (5 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 06/15] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 08/15] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
` (7 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 08/15] selftests/bpf: Fix use-after-free in xdp_metadata test
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (6 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 07/15] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 09/15] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
` (6 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 09/15] selftests/bpf: Fix double thread join in uprobe_multi_test
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (7 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 08/15] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:25 ` [PATCH bpf v3 10/15] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
` (5 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 10/15] selftests/bpf: Fix resource leaks caused by missing cleanups
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (8 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 09/15] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
@ 2026-02-20 22:25 ` Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 11/15] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
` (4 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:25 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] 24+ messages in thread* [PATCH bpf v3 11/15] selftests/bpf: Free bpf_object in test_sysctl
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (9 preceding siblings ...)
2026-02-20 22:25 ` [PATCH bpf v3 10/15] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
@ 2026-02-20 22:26 ` Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 12/15] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
` (3 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:26 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] 24+ messages in thread* [PATCH bpf v3 12/15] selftests/bpf: Fix array bounds warning in jit_disasm_helpers
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (10 preceding siblings ...)
2026-02-20 22:26 ` [PATCH bpf v3 11/15] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
@ 2026-02-20 22:26 ` Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 13/15] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
` (2 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:26 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] 24+ messages in thread* [PATCH bpf v3 13/15] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (11 preceding siblings ...)
2026-02-20 22:26 ` [PATCH bpf v3 12/15] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
@ 2026-02-20 22:26 ` Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 14/15] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 15/15] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:26 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] 24+ messages in thread* [PATCH bpf v3 14/15] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (12 preceding siblings ...)
2026-02-20 22:26 ` [PATCH bpf v3 13/15] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
@ 2026-02-20 22:26 ` Ihor Solodrai
2026-02-20 22:26 ` [PATCH bpf v3 15/15] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
14 siblings, 0 replies; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:26 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 c99776b03f52..774a22d624e7 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] 24+ messages in thread* [PATCH bpf v3 15/15] selftests/bpf: Don't override SIGSEGV handler with ASAN
2026-02-20 22:25 [PATCH bpf v3 00/15] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
` (13 preceding siblings ...)
2026-02-20 22:26 ` [PATCH bpf v3 14/15] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
@ 2026-02-20 22:26 ` Ihor Solodrai
2026-02-21 0:52 ` Eduard Zingerman
14 siblings, 1 reply; 24+ messages in thread
From: Ihor Solodrai @ 2026-02-20 22:26 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>
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] 24+ messages in thread* Re: [PATCH bpf v3 15/15] selftests/bpf: Don't override SIGSEGV handler with ASAN
2026-02-20 22:26 ` [PATCH bpf v3 15/15] selftests/bpf: Don't override SIGSEGV handler with ASAN Ihor Solodrai
@ 2026-02-21 0:52 ` Eduard Zingerman
0 siblings, 0 replies; 24+ messages in thread
From: Eduard Zingerman @ 2026-02-21 0:52 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 Fri, 2026-02-20 at 14:26 -0800, Ihor Solodrai wrote:
> 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>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
[...]
^ permalink raw reply [flat|nested] 24+ messages in thread