[PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN

Ihor Solodrai posted 14 patches 1 month, 2 weeks ago
There is a newer version of this series
tools/bpf/resolve_btfids/Makefile             |  7 +-
tools/bpf/resolve_btfids/main.c               | 78 ++++++++++++-------
tools/testing/selftests/bpf/DENYLIST.asan     |  3 +
tools/testing/selftests/bpf/Makefile          |  9 ++-
.../selftests/bpf/benchs/bench_trigger.c      |  9 +--
tools/testing/selftests/bpf/bpftool_helpers.c | 12 ++-
.../selftests/bpf/jit_disasm_helpers.c        | 18 ++---
.../bpf/prog_tests/cgrp_local_storage.c       |  4 +-
.../testing/selftests/bpf/prog_tests/dynptr.c |  5 +-
.../selftests/bpf/prog_tests/fd_array.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 +-
.../selftests/bpf/prog_tests/sockmap_basic.c  | 18 +++--
.../selftests/bpf/prog_tests/sockmap_listen.c |  2 +-
.../bpf/prog_tests/struct_ops_private_stack.c |  1 +
.../selftests/bpf/prog_tests/tc_opts.c        |  1 +
.../selftests/bpf/prog_tests/test_sysctl.c    | 22 ++++--
.../selftests/bpf/prog_tests/test_tc_tunnel.c |  5 +-
.../selftests/bpf/prog_tests/test_xsk.c       |  2 +
.../bpf/prog_tests/uprobe_multi_test.c        |  4 +-
.../selftests/bpf/prog_tests/verifier_log.c   |  2 +-
.../selftests/bpf/prog_tests/xdp_metadata.c   |  4 +-
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 +
28 files changed, 170 insertions(+), 99 deletions(-)
create mode 100644 tools/testing/selftests/bpf/DENYLIST.asan
[PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Ihor Solodrai 1 month, 2 weeks ago
This series includes various fixes aiming to enable test_progs run
with userspace address sanitizer on BPF CI.

The first patch 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.

The series is a pre-requisite for enabling "test_progs with ASAN"
workflow on BPF CI.

Ihor Solodrai (14):
  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()

 tools/bpf/resolve_btfids/Makefile             |  7 +-
 tools/bpf/resolve_btfids/main.c               | 78 ++++++++++++-------
 tools/testing/selftests/bpf/DENYLIST.asan     |  3 +
 tools/testing/selftests/bpf/Makefile          |  9 ++-
 .../selftests/bpf/benchs/bench_trigger.c      |  9 +--
 tools/testing/selftests/bpf/bpftool_helpers.c | 12 ++-
 .../selftests/bpf/jit_disasm_helpers.c        | 18 ++---
 .../bpf/prog_tests/cgrp_local_storage.c       |  4 +-
 .../testing/selftests/bpf/prog_tests/dynptr.c |  5 +-
 .../selftests/bpf/prog_tests/fd_array.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 +-
 .../selftests/bpf/prog_tests/sockmap_basic.c  | 18 +++--
 .../selftests/bpf/prog_tests/sockmap_listen.c |  2 +-
 .../bpf/prog_tests/struct_ops_private_stack.c |  1 +
 .../selftests/bpf/prog_tests/tc_opts.c        |  1 +
 .../selftests/bpf/prog_tests/test_sysctl.c    | 22 ++++--
 .../selftests/bpf/prog_tests/test_tc_tunnel.c |  5 +-
 .../selftests/bpf/prog_tests/test_xsk.c       |  2 +
 .../bpf/prog_tests/uprobe_multi_test.c        |  4 +-
 .../selftests/bpf/prog_tests/verifier_log.c   |  2 +-
 .../selftests/bpf/prog_tests/xdp_metadata.c   |  4 +-
 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 +
 28 files changed, 170 insertions(+), 99 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/DENYLIST.asan

-- 
2.53.0
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
> This series includes various fixes aiming to enable test_progs run
> with userspace address sanitizer on BPF CI.
> 
> The first patch 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.
> 
> The series is a pre-requisite for enabling "test_progs with ASAN"
> workflow on BPF CI.

Also, do we want to have ASAN enabled by default?
If it would be enabled for CI, people will need to deal with local
configuration anyway. It might make sense to put the default flags in
to save everyone the trouble of figuring out which flags CI uses.
Wdyt?

[...]
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Ihor Solodrai 1 month, 2 weeks ago
On 2/12/26 3:26 PM, Eduard Zingerman wrote:
> On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
>> This series includes various fixes aiming to enable test_progs run
>> with userspace address sanitizer on BPF CI.
>>
>> The first patch 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.
>>
>> The series is a pre-requisite for enabling "test_progs with ASAN"
>> workflow on BPF CI.
> 
> Also, do we want to have ASAN enabled by default?

I don't think so. At least not right away.

> If it would be enabled for CI, people will need to deal with local
> configuration anyway. It might make sense to put the default flags in
> to save everyone the trouble of figuring out which flags CI uses.
> Wdyt?

WIP CI changes add an *additional* test job, that builds only
test_progs default flavor with ASAN and runs it. Previous test jobs,
built with -static, are still there as usual.

There are tests that don't play well with ASAN such as BPF arena
tests, and some tests may be much slower when ASAN is enabled.
We still want to run them on CI.

I don't see why we should pick between asan everywhere or
nowhere. At the very least, CI should make sure selftests can build
successfully without the asan flags.

Additional job will catch most of bugs of the sort covered in this
series, and that is good enough I think.


> 
> [...]

Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Fri, 2026-02-13 at 09:56 -0800, Ihor Solodrai wrote:
> On 2/12/26 3:26 PM, Eduard Zingerman wrote:
> > On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
> > > This series includes various fixes aiming to enable test_progs run
> > > with userspace address sanitizer on BPF CI.
> > > 
> > > The first patch 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.
> > > 
> > > The series is a pre-requisite for enabling "test_progs with ASAN"
> > > workflow on BPF CI.
> > 
> > Also, do we want to have ASAN enabled by default?
> 
> I don't think so. At least not right away.
> 
> > If it would be enabled for CI, people will need to deal with local
> > configuration anyway. It might make sense to put the default flags in
> > to save everyone the trouble of figuring out which flags CI uses.
> > Wdyt?
> 
> WIP CI changes add an *additional* test job, that builds only
> test_progs default flavor with ASAN and runs it. Previous test jobs,
> built with -static, are still there as usual.
> 
> There are tests that don't play well with ASAN such as BPF arena
> tests, and some tests may be much slower when ASAN is enabled.
> We still want to run them on CI.

Fair enough.

> I don't see why we should pick between asan everywhere or
> nowhere. At the very least, CI should make sure selftests can build
> successfully without the asan flags.
> 
> Additional job will catch most of bugs of the sort covered in this
> series, and that is good enough I think.

My main concern is that when this fails on CI I will have to dig
through CI config to recover exact SAN_CFLAGS used. If not enabled by
default I'd still like to have a single knob like 'ASAN=t'.
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Ihor Solodrai 1 month, 2 weeks ago
On 2/13/26 10:09 AM, Eduard Zingerman wrote:
> On Fri, 2026-02-13 at 09:56 -0800, Ihor Solodrai wrote:
>> On 2/12/26 3:26 PM, Eduard Zingerman wrote:
>>> On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
>>>> This series includes various fixes aiming to enable test_progs run
>>>> with userspace address sanitizer on BPF CI.
>>>>
>>>> The first patch 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.
>>>>
>>>> The series is a pre-requisite for enabling "test_progs with ASAN"
>>>> workflow on BPF CI.
>>>
>>> Also, do we want to have ASAN enabled by default?
>>
>> I don't think so. At least not right away.
>>
>>> If it would be enabled for CI, people will need to deal with local
>>> configuration anyway. It might make sense to put the default flags in
>>> to save everyone the trouble of figuring out which flags CI uses.
>>> Wdyt?
>>
>> WIP CI changes add an *additional* test job, that builds only
>> test_progs default flavor with ASAN and runs it. Previous test jobs,
>> built with -static, are still there as usual.
>>
>> There are tests that don't play well with ASAN such as BPF arena
>> tests, and some tests may be much slower when ASAN is enabled.
>> We still want to run them on CI.
> 
> Fair enough.
> 
>> I don't see why we should pick between asan everywhere or
>> nowhere. At the very least, CI should make sure selftests can build
>> successfully without the asan flags.
>>
>> Additional job will catch most of bugs of the sort covered in this
>> series, and that is good enough I think.
> 
> My main concern is that when this fails on CI I will have to dig
> through CI config to recover exact SAN_CFLAGS used. If not enabled by
> default I'd still like to have a single knob like 'ASAN=t'.

I kinda have a switch like that [1]:

	if [[ -n "${SELFTESTS_BPF_ASAN:-}" ]]; then
		SELF_OPTS+=(SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer")
	[...]

Any ideas how to make this obvious in CI logs?
I could set -x in the script executing the make, but it may be noisy still.

[1] https://github.com/libbpf/ci/blob/selftests-asan/build-selftests/build_selftests.sh#L50-L51
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Fri, 2026-02-13 at 10:29 -0800, Ihor Solodrai wrote:

[...]

> I kinda have a switch like that [1]:
> 
> 	if [[ -n "${SELFTESTS_BPF_ASAN:-}" ]]; then
> 		SELF_OPTS+=(SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer")
> 	[...]
> 
> Any ideas how to make this obvious in CI logs?
> I could set -x in the script executing the make, but it may be noisy still.
> 
> [1] https://github.com/libbpf/ci/blob/selftests-asan/build-selftests/build_selftests.sh#L50-L51

I'd just add one more knob to the selftests makefile, e.g.:

  ifdef ASAN
    SAN_CFLAGS:="-fsanitize=address -fno-omit-frame-pointer"
  endif

And use it from CI as well.
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
> This series includes various fixes aiming to enable test_progs run
> with userspace address sanitizer on BPF CI.
> 
> The first patch 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.
> 
> The series is a pre-requisite for enabling "test_progs with ASAN"
> workflow on BPF CI.

I did an experiment:
- applied the diff as at the bottom of the email;
- compiled with export SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
  (using gcc 15.2.1);
- double-checked that resulting executable depends on libasan;
- did a test run: ./test_progs -a verifier_and.

The error report looks as follows:

  Caught signal #11!
  Stack trace:
  /lib64/libasan.so.8(+0x525e7) [0x7f6a506525e7]
  ./test_progs(crash_handler+0xb5) [0xd152c9]
  /lib64/libc.so.6(+0x19c30) [0x7f6a50427c30]
  /lib64/libasan.so.8(+0xdf4a) [0x7f6a5060df4a]
  /lib64/libasan.so.8(+0xe5bba) [0x7f6a506e5bba]
  ./test_progs() [0xd19ccc]
  ./test_progs(main+0xcf6) [0xd1aa79]
  /lib64/libc.so.6(+0x35f5) [0x7f6a504115f5]
  /lib64/libc.so.6(__libc_start_main+0x88) [0x7f6a504116a8]
  ./test_progs(_start+0x25) [0x401935]

Am I doing something wrong, or does test_progs signal handler
interfere with ASAN reporting?

[...]

---

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index a0a594de9007..3820077e74e4 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -46,7 +46,7 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
 endif
 
 CFLAGS += -g $(OPT_FLAGS) -rdynamic -std=gnu11                         \
-         -Wall -Werror -fno-omit-frame-pointer                         \
+         -Wall -fno-omit-frame-pointer                         \
          -Wno-unused-but-set-variable                                  \
          $(GENFLAGS) $(SAN_CFLAGS) $(LIBELF_CFLAGS)                    \
          -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR)          \
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 02a85dda30e6..8839e00167fa 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1924,7 +1924,7 @@ static void free_test_states(void)
                        free_subtest_state(&test_state->subtest_states[j]);
 
                free(test_state->subtest_states);
-               free(test_state->log_buf);
+               free(test_state->log_buf + 10);
                test_state->subtest_states = NULL;
                test_state->log_buf = NULL;
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Ihor Solodrai 1 month, 2 weeks ago
On 2/12/26 2:00 PM, Eduard Zingerman wrote:
> On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:
>> This series includes various fixes aiming to enable test_progs run
>> with userspace address sanitizer on BPF CI.
>>
>> The first patch 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.
>>
>> The series is a pre-requisite for enabling "test_progs with ASAN"
>> workflow on BPF CI.
> 
> I did an experiment:
> - applied the diff as at the bottom of the email;
> - compiled with export SAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
>   (using gcc 15.2.1);
> - double-checked that resulting executable depends on libasan;
> - did a test run: ./test_progs -a verifier_and.
> 
> The error report looks as follows:
> 
>   Caught signal #11!
>   Stack trace:
>   /lib64/libasan.so.8(+0x525e7) [0x7f6a506525e7]
>   ./test_progs(crash_handler+0xb5) [0xd152c9]
>   /lib64/libc.so.6(+0x19c30) [0x7f6a50427c30]
>   /lib64/libasan.so.8(+0xdf4a) [0x7f6a5060df4a]
>   /lib64/libasan.so.8(+0xe5bba) [0x7f6a506e5bba]
>   ./test_progs() [0xd19ccc]
>   ./test_progs(main+0xcf6) [0xd1aa79]
>   /lib64/libc.so.6(+0x35f5) [0x7f6a504115f5]
>   /lib64/libc.so.6(__libc_start_main+0x88) [0x7f6a504116a8]
>   ./test_progs(_start+0x25) [0x401935]
> 
> Am I doing something wrong, or does test_progs signal handler
> interfere with ASAN reporting?
> 
> [...]
> 
> ---
> 
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index a0a594de9007..3820077e74e4 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -46,7 +46,7 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
>  endif
>  
>  CFLAGS += -g $(OPT_FLAGS) -rdynamic -std=gnu11                         \
> -         -Wall -Werror -fno-omit-frame-pointer                         \
> +         -Wall -fno-omit-frame-pointer                         \

I think you've cheated a little bit here, because with -Werror 

    free(test_state->log_buf + 10);

doesn't compile:

    test_progs.c: In function ‘free_test_states’:
    test_progs.c:1927:17: error: ‘free’ called on pointer ‘*test_state.log_buf’ with nonzero offset 10 [-Werror=free-nonheap-object]
     1927 |                 free(test_state->log_buf + 10);
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    make: *** [Makefile:767: /home/isolodrai/kernels/bpf-next/tools/testing/selftests/bpf/test_progs.o] Error 1
    make: *** Waiting for unfinished jobs....

If it's removed, then I can reproduce the same stacktrace, which AFAIU
is an invalid dereference inside the ASAN itself.

I'm no expert here, but it appears ASAN only tracks exact pointers? Or
maybe the assumption is that dumb errors like this one are caught at
compile time, so no need to check for them at runtime?

It could also be a bug in ASAN or gcc. I don't want to assume that, but
after unexpected adventures with llvm-objcopy I wouldn't be surprised.

I think a conclusion here is that ASAN doesn't guarantee the absence
of segfaults at runtime. It just helps to catch certain bugs.

I tried to trigger use-after-free, but also get a segfault.
Apparently at that point log_buf is already NULL.

diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 02a85dda30e6..5ff1d9fc5e4d 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1924,7 +1924,10 @@ static void free_test_states(void)
                        free_subtest_state(&test_state->subtest_states[j]);
 
                free(test_state->subtest_states);
+               printf("log_buf = %p\n", test_state->log_buf);
                free(test_state->log_buf);
+               char c = test_state->log_buf[0];
+               printf("c: %c\n", c);
                test_state->subtest_states = NULL;
                test_state->log_buf = NULL;
        }


#522/1   verifier_and/invalid and of negative number:OKtest_progs -v -a verifier_and
#522/2   verifier_and/invalid and of negative number @unpriv:OK
#522/3   verifier_and/invalid range check:OK
#522/4   verifier_and/invalid range check @unpriv:OK
#522/5   verifier_and/check known subreg with unknown reg:OK
#522/6   verifier_and/check known subreg with unknown reg @unpriv:OK
#522     verifier_and:OK
Summary: 1/6 PASSED, 0 SKIPPED, 0 FAILED
log_buf = (nil)
tester_init:PASS:tester_log_buf 0 nsec
process_subtest:PASS:obj_open_mem 0 nsec
process_subtest:PASS:specs_alloc 0 nsec
#522     verifier_and:FAIL
Caught signal #11!
Stack trace:
/lib64/libasan.so.8(+0x525e7) [0x7f311290e5e7]
./test_progs(crash_handler+0xb5) [0xd15af6]
/lib64/libc.so.6(+0x1a290) [0x7f311269f290]
./test_progs() [0xd1a595]
./test_progs(main+0xcf6) [0xd1b35d]
/lib64/libc.so.6(+0x35b5) [0x7f31126885b5]
/lib64/libc.so.6(__libc_start_main+0x88) [0x7f3112688668]
./test_progs(_start+0x25) [0x401865]
[  246.835249] test_progs[232]: segfault at 0 ip 0000000000d1a595 sp 00007ffd8e64cc00 error 4 in test_progs[91a595,400000+a34000] likely on CPU 0 (core 0, socket 0)
[  246.838738] Code: 48 81 c2 00 80 ff 7f 0f b6 12 84 d2 40 0f 95 c6 48 89 c7 83 e7 07 40 38 d7 0f 9d c2 21 f2 84 d2 74 08 48 89 c7 e8 1b 6a 6e ff <0f> b6 01 88 45 ef 0f be 45 ef 89 c6 bf c0 58 b2 01 b8 00 00 00 00
Segmentation fault         ./test_progs -a verifier_and


>           -Wno-unused-but-set-variable                                  \
>           $(GENFLAGS) $(SAN_CFLAGS) $(LIBELF_CFLAGS)                    \
>           -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR)          \
> diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
> index 02a85dda30e6..8839e00167fa 100644
> --- a/tools/testing/selftests/bpf/test_progs.c
> +++ b/tools/testing/selftests/bpf/test_progs.c
> @@ -1924,7 +1924,7 @@ static void free_test_states(void)
>                         free_subtest_state(&test_state->subtest_states[j]);
>  
>                 free(test_state->subtest_states);
> -               free(test_state->log_buf);
> +               free(test_state->log_buf + 10);
>                 test_state->subtest_states = NULL;
>                 test_state->log_buf = NULL;

Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Thu, 2026-02-12 at 15:57 -0800, Ihor Solodrai wrote:

[...]

> >  CFLAGS += -g $(OPT_FLAGS) -rdynamic -std=gnu11                         \
> > -         -Wall -Werror -fno-omit-frame-pointer                         \
> > +         -Wall -fno-omit-frame-pointer                         \
> 
> I think you've cheated a little bit here, because with -Werror

It's just a model of a memory error, see below an example that does
not generate compiler warnings.

> If it's removed, then I can reproduce the same stacktrace, which AFAIU
> is an invalid dereference inside the ASAN itself.

See below, if I remove custom signal handler there is a regular ASAN
error message:

  ==156==ERROR: AddressSanitizer: SEGV on unknown address 0xfffffffffffffffa (pc 0x7fa03160df4a bp 0x7fa0317bc980 sp 0x7ffee7c85170 T0)
  ==156==The signal is caused by a WRITE memory access.
      #0 0x7fa03160df4a in __asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (/lib64/libasan.so.8+0xdf4a) (BuildId: d3cb6206dff19da52969c009f4cd93611901c478)
      #1 0x7fa0316e5bb9 in free.part.0 (/lib64/libasan.so.8+0xe5bb9) (BuildId: d3cb6206dff19da52969c009f4cd93611901c478)
      #2 0x000000d19cd9 in free_test_states /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:1930
      #3 0x000000d1a897 in main /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:2107
      #4 0x7fa0313c45f4 in __libc_start_call_main (/lib64/libc.so.6+0x35f4) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
      #5 0x7fa0313c46a7 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x36a7) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
      #6 0x000000401934 in _start (/home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs+0x401934) (BuildId: 9190db005d475ee7a8e9294bb32cfbd520c330dc)
  
  ==156==Register values:
  rax = 0x0000000000000002  rbx = 0x000000000000000a  rcx = 0x0000000000000000  rdx = 0x0000000000000003  
  rdi = 0x000000000000000a  rsi = 0x000000000000000a  rbp = 0x00007fa0317bc980  rsp = 0x00007ffee7c85170  
   r8 = 0x00007ffee7c851d0   r9 = 0x0000000000000001  r10 = 0x0000000000000005  r11 = 0x0000000000401935  
  r12 = 0x00007ffee7c851d0  r13 = 0xfffffffffffffffa  r14 = 0x0000000000000001  r15 = 0x0000000000000000  
  AddressSanitizer can not provide additional info.
  SUMMARY: AddressSanitizer: SEGV /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:1930 in free_test_states

So, there is indeed a conflict between test_progs signal handler and
ASAN default signal handler.

[...]

--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1913,6 +1913,8 @@ static int worker_main(int sock)
        return 0;
 }
 
+void *ptr;
+
 static void free_test_states(void)
 {
        int i, j;
@@ -1924,7 +1926,8 @@ static void free_test_states(void)
                        free_subtest_state(&test_state->subtest_states[j]);
 
                free(test_state->subtest_states);
-               free(test_state->log_buf);
+               ptr = test_state->log_buf + 10;
+               free(ptr);
                test_state->subtest_states = NULL;
                test_state->log_buf = NULL;
        }
@@ -1944,13 +1947,15 @@ int main(int argc, char **argv)
                .parser = parse_arg,
                .doc = argp_program_doc,
        };
-       struct sigaction sigact = {
-               .sa_handler = crash_handler,
-               .sa_flags = SA_RESETHAND,
-               };
+       /*
+        * struct sigaction sigact = {
+        *      .sa_handler = crash_handler,
+        *      .sa_flags = SA_RESETHAND,
+        *      };
+        */
        int err, i;
 
-       sigaction(SIGSEGV, &sigact, NULL);
+       //sigaction(SIGSEGV, &sigact, NULL);
 
        env.stdout_saved = stdout;
        env.stderr_saved = stderr;
Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Ihor Solodrai 1 month, 2 weeks ago
On 2/12/26 4:23 PM, Eduard Zingerman wrote:
> On Thu, 2026-02-12 at 15:57 -0800, Ihor Solodrai wrote:
> 
> [...]
> 
>>>  CFLAGS += -g $(OPT_FLAGS) -rdynamic -std=gnu11                         \
>>> -         -Wall -Werror -fno-omit-frame-pointer                         \
>>> +         -Wall -fno-omit-frame-pointer                         \
>>
>> I think you've cheated a little bit here, because with -Werror
> 
> It's just a model of a memory error, see below an example that does
> not generate compiler warnings.
> 
>> If it's removed, then I can reproduce the same stacktrace, which AFAIU
>> is an invalid dereference inside the ASAN itself.
> 
> See below, if I remove custom signal handler there is a regular ASAN
> error message:
> 
>   ==156==ERROR: AddressSanitizer: SEGV on unknown address 0xfffffffffffffffa (pc 0x7fa03160df4a bp 0x7fa0317bc980 sp 0x7ffee7c85170 T0)
>   ==156==The signal is caused by a WRITE memory access.
>       #0 0x7fa03160df4a in __asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (/lib64/libasan.so.8+0xdf4a) (BuildId: d3cb6206dff19da52969c009f4cd93611901c478)
>       #1 0x7fa0316e5bb9 in free.part.0 (/lib64/libasan.so.8+0xe5bb9) (BuildId: d3cb6206dff19da52969c009f4cd93611901c478)
>       #2 0x000000d19cd9 in free_test_states /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:1930
>       #3 0x000000d1a897 in main /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:2107
>       #4 0x7fa0313c45f4 in __libc_start_call_main (/lib64/libc.so.6+0x35f4) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
>       #5 0x7fa0313c46a7 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x36a7) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
>       #6 0x000000401934 in _start (/home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs+0x401934) (BuildId: 9190db005d475ee7a8e9294bb32cfbd520c330dc)
>   
>   ==156==Register values:
>   rax = 0x0000000000000002  rbx = 0x000000000000000a  rcx = 0x0000000000000000  rdx = 0x0000000000000003  
>   rdi = 0x000000000000000a  rsi = 0x000000000000000a  rbp = 0x00007fa0317bc980  rsp = 0x00007ffee7c85170  
>    r8 = 0x00007ffee7c851d0   r9 = 0x0000000000000001  r10 = 0x0000000000000005  r11 = 0x0000000000401935  
>   r12 = 0x00007ffee7c851d0  r13 = 0xfffffffffffffffa  r14 = 0x0000000000000001  r15 = 0x0000000000000000  
>   AddressSanitizer can not provide additional info.
>   SUMMARY: AddressSanitizer: SEGV /home/eddy/work/bpf-next/tools/testing/selftests/bpf/test_progs.c:1930 in free_test_states
> 
> So, there is indeed a conflict between test_progs signal handler and
> ASAN default signal handler.

As it turns out, only one signal handler can be installed at a time [1].
From man [2]:

    The sigaction() system call is used to *change* the action taken by
    a process on receipt of a specific signal.

So what happens is test_prog's custom signal handler *overwrites* ASAN's
signal handler leading to the weirdness we are seeing.

[1] https://stackoverflow.com/questions/17102919/is-it-valid-to-have-multiple-signal-handlers-for-same-signal
[2] https://man7.org/linux/man-pages/man2/sigaction.2.html

We should probably do then:

diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 02a85dda30e6..77a36f6ca352 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1672,14 +1672,15 @@ static void server_main(void)
 {
        pthread_t *dispatcher_threads;
        struct dispatch_data *data;
+       int i;
+
+#ifndef __SANITIZE_ADDRESS__
        struct sigaction sigact_int = {
                .sa_handler = sigint_handler,
                .sa_flags = SA_RESETHAND,
        };
-       int i;
-
        sigaction(SIGINT, &sigact_int, NULL);
-
+#endif
        dispatcher_threads = calloc(sizeof(pthread_t), env.workers);
        data = calloc(sizeof(struct dispatch_data), env.workers);


> 
> [...]
> 
> --- a/tools/testing/selftests/bpf/test_progs.c
> +++ b/tools/testing/selftests/bpf/test_progs.c
> @@ -1913,6 +1913,8 @@ static int worker_main(int sock)
>         return 0;
>  }
>  
> +void *ptr;
> +
>  static void free_test_states(void)
>  {
>         int i, j;
> @@ -1924,7 +1926,8 @@ static void free_test_states(void)
>                         free_subtest_state(&test_state->subtest_states[j]);
>  
>                 free(test_state->subtest_states);
> -               free(test_state->log_buf);
> +               ptr = test_state->log_buf + 10;
> +               free(ptr);
>                 test_state->subtest_states = NULL;
>                 test_state->log_buf = NULL;
>         }
> @@ -1944,13 +1947,15 @@ int main(int argc, char **argv)
>                 .parser = parse_arg,
>                 .doc = argp_program_doc,
>         };
> -       struct sigaction sigact = {
> -               .sa_handler = crash_handler,
> -               .sa_flags = SA_RESETHAND,
> -               };
> +       /*
> +        * struct sigaction sigact = {
> +        *      .sa_handler = crash_handler,
> +        *      .sa_flags = SA_RESETHAND,
> +        *      };
> +        */
>         int err, i;
>  
> -       sigaction(SIGSEGV, &sigact, NULL);
> +       //sigaction(SIGSEGV, &sigact, NULL);
>  
>         env.stdout_saved = stdout;
>         env.stderr_saved = stderr;

Re: [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Fri, 2026-02-13 at 08:13 -0800, Ihor Solodrai wrote:

[...]

> So what happens is test_prog's custom signal handler *overwrites* ASAN's
> signal handler leading to the weirdness we are seeing.

That's what I meant by conflict.

> 
> [1] https://stackoverflow.com/questions/17102919/is-it-valid-to-have-multiple-signal-handlers-for-same-signal
> [2] https://man7.org/linux/man-pages/man2/sigaction.2.html
> 
> We should probably do then:
> 
> diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
> index 02a85dda30e6..77a36f6ca352 100644
> --- a/tools/testing/selftests/bpf/test_progs.c
> +++ b/tools/testing/selftests/bpf/test_progs.c
> @@ -1672,14 +1672,15 @@ static void server_main(void)
>  {
>         pthread_t *dispatcher_threads;
>         struct dispatch_data *data;
> +       int i;
> +
> +#ifndef __SANITIZE_ADDRESS__
>         struct sigaction sigact_int = {
>                 .sa_handler = sigint_handler,
>                 .sa_flags = SA_RESETHAND,
>         };
> -       int i;
> -
>         sigaction(SIGINT, &sigact_int, NULL);
> -
> +#endif
>         dispatcher_threads = calloc(sizeof(pthread_t), env.workers);
>         data = calloc(sizeof(struct dispatch_data), env.workers);

ASAN's stack trace looks nicer compared to what libunwind generates.
On the other hand, test_progs.c:carsh_handler() prints pending test log.
There is an option to remember old handler returned by sigaction and
call it from the crash_handler (thus invoking ASAN's handler),
but the complication is probably not worth it.
I think this part is good as it is, sorry for the noise.

[...]