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