Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Add selftest for check_stack_max_depth bug

Use the bpf_timer_set_callback helper to mark timer_cb as an async
callback, and put a direct call to timer_cb in the main subprog.

As the check_stack_max_depth happens after the do_check pass, the order
does not matter. Without the previous fix, the test passes successfully.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20230705144730.235802-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
906bd22a 5415ccd5

+49
+9
tools/testing/selftests/bpf/prog_tests/async_stack_depth.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <test_progs.h> 3 + 4 + #include "async_stack_depth.skel.h" 5 + 6 + void test_async_stack_depth(void) 7 + { 8 + RUN_TESTS(async_stack_depth); 9 + }
+40
tools/testing/selftests/bpf/progs/async_stack_depth.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <vmlinux.h> 3 + #include <bpf/bpf_helpers.h> 4 + 5 + #include "bpf_misc.h" 6 + 7 + struct hmap_elem { 8 + struct bpf_timer timer; 9 + }; 10 + 11 + struct { 12 + __uint(type, BPF_MAP_TYPE_HASH); 13 + __uint(max_entries, 64); 14 + __type(key, int); 15 + __type(value, struct hmap_elem); 16 + } hmap SEC(".maps"); 17 + 18 + __attribute__((noinline)) 19 + static int timer_cb(void *map, int *key, struct bpf_timer *timer) 20 + { 21 + volatile char buf[256] = {}; 22 + return buf[69]; 23 + } 24 + 25 + SEC("tc") 26 + __failure __msg("combined stack size of 2 calls") 27 + int prog(struct __sk_buff *ctx) 28 + { 29 + struct hmap_elem *elem; 30 + volatile char buf[256] = {}; 31 + 32 + elem = bpf_map_lookup_elem(&hmap, &(int){0}); 33 + if (!elem) 34 + return 0; 35 + 36 + timer_cb(NULL, NULL, NULL); 37 + return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0]; 38 + } 39 + 40 + char _license[] SEC("license") = "GPL";