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 __attribute__((noinline))
26 static int bad_timer_cb(void *map, int *key, struct bpf_timer *timer)
27 {
28 	volatile char buf[300] = {};
29 	return buf[255] + timer_cb(NULL, NULL, NULL);
30 }
31 
32 SEC("tc")
33 __failure __msg("combined stack size of 2 calls is")
34 int pseudo_call_check(struct __sk_buff *ctx)
35 {
36 	struct hmap_elem *elem;
37 	volatile char buf[256] = {};
38 
39 	elem = bpf_map_lookup_elem(&hmap, &(int){0});
40 	if (!elem)
41 		return 0;
42 
43 	timer_cb(NULL, NULL, NULL);
44 	return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0];
45 }
46 
47 SEC("tc")
48 __failure __msg("combined stack size of 2 calls is")
49 int async_call_root_check(struct __sk_buff *ctx)
50 {
51 	struct hmap_elem *elem;
52 	volatile char buf[256] = {};
53 
54 	elem = bpf_map_lookup_elem(&hmap, &(int){0});
55 	if (!elem)
56 		return 0;
57 
58 	return bpf_timer_set_callback(&elem->timer, bad_timer_cb) + buf[0];
59 }
60 
61 char _license[] SEC("license") = "GPL";
62