1// SPDX-License-Identifier: GPL-2.0
2#include <vmlinux.h>
3#include <bpf/bpf_helpers.h>
4
5#include "bpf_misc.h"
6
7struct hmap_elem {
8	struct bpf_timer timer;
9};
10
11struct {
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))
19static 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))
26static 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
32SEC("tc")
33__failure __msg("combined stack size of 2 calls is")
34int 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
47SEC("tc")
48__failure __msg("combined stack size of 2 calls is")
49int 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
61char _license[] SEC("license") = "GPL";
62