[PATCH bpf-next v2 8/8] selftests/bpf: add tests to validate KASAN on JIT programs
Yonghong Song
yonghong.song at linux.dev
Fri Jun 5 08:47:19 PDT 2026
On 6/4/26 1:22 PM, Alexis Lothoré (eBPF Foundation) wrote:
> Add a basic KASAN test runner that loads and test-run programs that can
> trigger memory management bugs. The test captures kernel logs and ensure
> that the expected KASAN splat is emitted by searching for the
> corresponding first lines in the report, hence validated that the needed
> instrumentation has been inserted by the JIT compiler before the
> relevant memory accesses.
>
> The runner covers different cases and settings: in the nominal case, it
> validates kasan reports on basic instructions (on all supported accesses
> sizes) but also when report _should not_ be emitted (eg: for accesses on
> program stack). The runner also comes with a few specialized tests that
> are then not executed for all sizes/locations. A few of those tests
> depends on cpuv4 (load_acquire and store_release).
>
> # ./test_progs -a kasan
> #164/1 kasan/st_1_not_on_stack:OK
> #164/2 kasan/st_1_on_stack:OK
> #164/3 kasan/st_2_not_on_stack:OK
> #164/4 kasan/st_2_on_stack:OK
> #164/5 kasan/st_4_not_on_stack:OK
> #164/6 kasan/st_4_on_stack:OK
> #164/7 kasan/st_8_not_on_stack:OK
> #164/8 kasan/st_8_on_stack:OK
> #164/9 kasan/stx_1_not_on_stack:OK
> #164/10 kasan/stx_1_on_stack:OK
> #164/11 kasan/stx_2_not_on_stack:OK
> #164/12 kasan/stx_2_on_stack:OK
> #164/13 kasan/stx_4_not_on_stack:OK
> #164/14 kasan/stx_4_on_stack:OK
> #164/15 kasan/stx_8_not_on_stack:OK
> #164/16 kasan/stx_8_on_stack:OK
> #164/17 kasan/ldx_1_not_on_stack:OK
> #164/18 kasan/ldx_1_on_stack:OK
> #164/19 kasan/ldx_2_not_on_stack:OK
> #164/20 kasan/ldx_2_on_stack:OK
> #164/21 kasan/ldx_4_not_on_stack:OK
> #164/22 kasan/ldx_4_on_stack:OK
> #164/23 kasan/ldx_8_not_on_stack:OK
> #164/24 kasan/ldx_8_on_stack:OK
> #164/25 kasan/simple_atomic_4_not_on_stack:OK
> #164/26 kasan/simple_atomic_4_on_stack:OK
> #164/27 kasan/simple_atomic_8_not_on_stack:OK
> #164/28 kasan/simple_atomic_8_on_stack:OK
> #164/29 kasan/load_acquire_1_not_on_stack:SKIP
> #164/30 kasan/load_acquire_1_on_stack:SKIP
> #164/31 kasan/load_acquire_2_not_on_stack:SKIP
> #164/32 kasan/load_acquire_2_on_stack:SKIP
> #164/33 kasan/load_acquire_4_not_on_stack:SKIP
> #164/34 kasan/load_acquire_4_on_stack:SKIP
> #164/35 kasan/load_acquire_8_not_on_stack:SKIP
> #164/36 kasan/load_acquire_8_on_stack:SKIP
> #164/37 kasan/store_release_1_not_on_stack:SKIP
> #164/38 kasan/store_release_1_on_stack:SKIP
> #164/39 kasan/store_release_2_not_on_stack:SKIP
> #164/40 kasan/store_release_2_on_stack:SKIP
> #164/41 kasan/store_release_4_not_on_stack:SKIP
> #164/42 kasan/store_release_4_on_stack:SKIP
> #164/43 kasan/store_release_8_not_on_stack:SKIP
> #164/44 kasan/store_release_8_on_stack:SKIP
> #164/45 kasan/ldx_patched:OK
> #164/46 kasan/stack_and_non_stack:OK
> #164 kasan:OK (SKIP: 16/46)
> Summary: 1/30 PASSED, 16 SKIPPED, 0 FAILED
On my qemu run, I got a bunch of failures like below:
[root at arch-fb-vm1 bpf]# ./test_progs -n 164
test_kasan:PASS:alloc test ctx 0 nsec
gzopen /boot/config-7.1.0-rc5-gec86c8156bd6: No such file or directory
test_kasan:PASS:open prog 0 nsec
test_kasan:PASS:find rnd_hi32 prog 0 nsec
...
All error logs:
test_kasan:PASS:alloc test ctx 0 nsec
gzopen /boot/config-7.1.0-rc5-gec86c8156bd6: No such file or directory
test_kasan:PASS:open prog 0 nsec
test_kasan:PASS:find rnd_hi32 prog 0 nsec
test_kasan:PASS:load prog 0 nsec
test_kasan:PASS:open kernel logs 0 nsec
test_kasan:PASS:get map 0 nsec
test_kasan:PASS:set map 0 nsec
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/1 kasan/st_1_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/3 kasan/st_2_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/5 kasan/st_4_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/7 kasan/st_8_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/9 kasan/stx_1_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/11 kasan/stx_2_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/13 kasan/stx_4_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/15 kasan/stx_8_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/17 kasan/ldx_1_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/19 kasan/ldx_2_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/21 kasan/ldx_4_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/23 kasan/ldx_8_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/25 kasan/simple_atomic_4_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/27 kasan/simple_atomic_8_not_on_stack:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/45 kasan/ldx_patched:FAIL
run_subtest_with_size_and_location:PASS:find test prog 0 nsec
run_subtest_with_size_and_location:PASS:fetch loaded program info 0 nsec
run_subtest_with_size_and_location:PASS:run prog 0 nsec
run_subtest_with_size_and_location:PASS:read kernel logs 0 nsec
run_subtest_with_size_and_location:FAIL:report should be generated unexpected error: 1 (errno 11)
#164/46 kasan/stack_and_non_stack:FAIL
#164 kasan:FAIL
I checked the subtest 164/1,
For
ret = check_kasan_report_in_kernel_logs(klog_buffer, ctx,
test->is_write, access_size);
if (on_stack || test->expect_no_report)
ASSERT_NEQ(ret, 0, "no report should be generated");
else
ASSERT_OK(ret, "report should be generated");
the ret is equal to 1 as klog_buffer is empty. This caused the failure.
>
> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore at bootlin.com>
> ---
> Changes in v2:
> - simplify tests by just manually poisoning test areas with a dedicated
> kfunc
> - introduce one prog per covered instruction family
> - make sure that tests do not consume kernel logs (use /dev/kmgs rather
> than klogctl)
> - add tests for stack accesses:
> - marking correctly set when there are diverging verifier states
> leading to different memory types
> - marking kept in sync with prog when it is patched
> ---
> tools/testing/selftests/bpf/prog_tests/kasan.c | 356 +++++++++++++++++++
> tools/testing/selftests/bpf/progs/kasan.c | 382 +++++++++++++++++++++
> .../testing/selftests/bpf/test_kmods/bpf_testmod.c | 22 ++
> 3 files changed, 760 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/kasan.c b/tools/testing/selftests/bpf/prog_tests/kasan.c
> new file mode 100644
> index 000000000000..adf61e230ec9
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/kasan.c
> @@ -0,0 +1,356 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +#include <bpf/bpf.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <linux/if_ether.h>
> +#include <unistd.h>
> +#include <test_progs.h>
> +#include <unpriv_helpers.h>
> +#include "kasan.skel.h"
> +
> +#define SUBTEST_NAME_MAX_LEN 128
> +#define PROG_NAME_MAX_LEN 128
> +
> +#define MAX_LOG_SIZE (8 * 1024)
> +#define READ_CHUNK_SIZE 256
> +
> +#define KASAN_PATTERN_SLAB_UAF "BUG: KASAN: slab-use-after-free " \
> + "in bpf_prog_%02x%02x%02x%02x%02x%02x%02x%02x_%s"
> +#define KASAN_PATTERN_REPORT "%s of size %d at addr"
> +
> +static char klog_buffer[MAX_LOG_SIZE];
> +
> +struct test_spec {
> + char *prog_type;
> + bool is_write;
> + bool only_32_or_64;
> + bool needs_load_acq_store_rel;
> + bool skip_multi_size_testing;
> + bool skip_on_stack_testing;
> + int run_size;
> + bool expect_no_report;
expect_no_report is not set in the code. The only usage is in
if (on_stack || test->expect_no_report)
ASSERT_NEQ(ret, 0, "no report should be generated");
else
ASSERT_OK(ret, "report should be generated");
> + bool rnd_hi32;
> +};
> +
> +struct kasan_write_val {
> + __u8 data_1;
> + __u16 data_2;
> + __u32 data_4;
> + __u64 data_8;
> +};
> +
>
[...]
More information about the linux-arm-kernel
mailing list