On Mon, 2024-07-01 at 17:22 +0200, Daniel Borkmann wrote: > On 7/1/24 3:24 PM, Ilya Leoshkevich wrote: > > Check that __sync_*() functions don't cause kernel panics when > > handling > > freed arena pages. > > > > x86_64 does not support some arena atomics yet, and aarch64 may or > > may > > not support them, based on the availability of LSE atomics at run > > time. > > Do not enable this test for these architectures for simplicity. > > > > Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> > > --- > > .../selftests/bpf/prog_tests/arena_atomics.c | 18 +++++ > > .../selftests/bpf/progs/arena_atomics.c | 76 > > +++++++++++++++++++ > > 2 files changed, 94 insertions(+) > > > > diff --git a/tools/testing/selftests/bpf/prog_tests/arena_atomics.c > > b/tools/testing/selftests/bpf/prog_tests/arena_atomics.c > > index 0807a48a58ee..26e7c06c6cb4 100644 > > --- a/tools/testing/selftests/bpf/prog_tests/arena_atomics.c > > +++ b/tools/testing/selftests/bpf/prog_tests/arena_atomics.c > > @@ -146,6 +146,22 @@ static void test_xchg(struct arena_atomics > > *skel) > > ASSERT_EQ(skel->arena->xchg32_result, 1, "xchg32_result"); > > } > > > > +static void test_uaf(struct arena_atomics *skel) > > +{ > > + LIBBPF_OPTS(bpf_test_run_opts, topts); > > + int err, prog_fd; > > + > > + /* No need to attach it, just run it directly */ > > + prog_fd = bpf_program__fd(skel->progs.uaf); > > + err = bpf_prog_test_run_opts(prog_fd, &topts); > > + if (!ASSERT_OK(err, "test_run_opts err")) > > + return; > > + if (!ASSERT_OK(topts.retval, "test_run_opts retval")) > > + return; > > + > > + ASSERT_EQ(skel->arena->uaf_recovery_fails, 0, > > "uaf_recovery_fails"); > > +} > > + > > void test_arena_atomics(void) > > { > > struct arena_atomics *skel; > > @@ -180,6 +196,8 @@ void test_arena_atomics(void) > > test_cmpxchg(skel); > > if (test__start_subtest("xchg")) > > test_xchg(skel); > > + if (test__start_subtest("uaf")) > > + test_uaf(skel); > > > > cleanup: > > arena_atomics__destroy(skel); > > diff --git a/tools/testing/selftests/bpf/progs/arena_atomics.c > > b/tools/testing/selftests/bpf/progs/arena_atomics.c > > index 55f10563208d..0ea310713fe6 100644 > > --- a/tools/testing/selftests/bpf/progs/arena_atomics.c > > +++ b/tools/testing/selftests/bpf/progs/arena_atomics.c > > @@ -176,3 +176,79 @@ int xchg(const void *ctx) > > > > return 0; > > } > > + > > +__u64 __arena uaf_sink; > > +volatile __u64 __arena uaf_recovery_fails; > > + > > +SEC("syscall") > > +int uaf(const void *ctx) > > +{ > > + if (pid != (bpf_get_current_pid_tgid() >> 32)) > > + return 0; > > +#if defined(ENABLE_ATOMICS_TESTS) && !defined(__TARGET_ARCH_arm64) > > && \ > > + !defined(__TARGET_ARCH_x86) > > + __u32 __arena *page32; > > + __u64 __arena *page64; > > + void __arena *page; > > + > > Looks like the selftest is failing s390x-gcc CI build, ptal : > > > https://github.com/kernel-patches/bpf/actions/runs/9745362735/job/26893165998 > > [...] > CLNG-BPF [test_maps] btf__core_reloc_size.bpf.o > CLNG-BPF [test_maps] bind6_prog.bpf.o > progs/arena_atomics.c:190:8: error: 'section' attribute only > applies to functions, global variables, Objective-C methods, and > Objective-C properties > 190 | __u32 __arena *page32; > | ^ > progs/arena_atomics.c:32:17: note: expanded from macro '__arena' > 32 | #define __arena SEC(".addr_space.1") > | ^ > > /tmp/work/bpf/bpf/tools/testing/selftests/bpf/tools/include/bpf/bpf_h > elpers.h:40:17: note: expanded from macro 'SEC' > 40 | __attribute__((section(name), > used)) \ > | ^ > progs/arena_atomics.c:191:8: error: 'section' attribute only > applies to functions, global variables, Objective-C methods, and > Objective-C properties > 191 | __u64 __arena *page64; > | ^ > progs/arena_atomics.c:32:17: note: expanded from macro '__arena' > 32 | #define __arena SEC(".addr_space.1") > | ^ > > /tmp/work/bpf/bpf/tools/testing/selftests/bpf/tools/include/bpf/bpf_h > elpers.h:40:17: note: expanded from macro 'SEC' > 40 | __attribute__((section(name), > used)) \ > | ^ > progs/arena_atomics.c:192:7: error: 'section' attribute only > applies to functions, global variables, Objective-C methods, and > Objective-C properties > 192 | void __arena *page; > | ^ > progs/arena_atomics.c:32:17: note: expanded from macro '__arena' > 32 | #define __arena SEC(".addr_space.1") > | ^ > > /tmp/work/bpf/bpf/tools/testing/selftests/bpf/tools/include/bpf/bpf_h > elpers.h:40:17: note: expanded from macro 'SEC' > 40 | __attribute__((section(name), > used)) \ > | ^ > 3 errors generated. > CLNG-BPF [test_maps] cpumask_success.bpf.o > make: *** [Makefile:654: > /tmp/work/bpf/bpf/tools/testing/selftests/bpf/arena_atomics.bpf.o] > Error 1 > make: *** Waiting for unfinished jobs.... > CLNG-BPF [test_maps] fib_lookup.bpf.o > make: Leaving directory > '/tmp/work/bpf/bpf/tools/testing/selftests/bpf' > Error: Process completed with exit code 2. Apparently this particular test redefines the __arena macro. The "common" definition is __attribute__((address_space(1))) for LLVM, and nothing for GCC. I assume this doesn't work if one wants to have globals inside the arena, hence the redefinition. Unfortunately the redefinition breaks the usage of __arena in pointer types. I think I will replace the redefinition with a separate __arena_global macro.