0001
0002
0003
0004 #include "vmlinux.h"
0005 #include <bpf/bpf_helpers.h>
0006 #include "bpf_misc.h"
0007
0008 char _license[] SEC("license") = "GPL";
0009
0010 struct callback_ctx {
0011 int output;
0012 };
0013
0014 struct {
0015 __uint(type, BPF_MAP_TYPE_HASH);
0016 __uint(max_entries, 32);
0017 __type(key, int);
0018 __type(value, int);
0019 } map1 SEC(".maps");
0020
0021
0022 u32 nested_callback_nr_loops;
0023 u32 stop_index = -1;
0024 u32 nr_loops;
0025 int pid;
0026 int callback_selector;
0027
0028
0029
0030
0031 int nr_loops_returned;
0032 int g_output;
0033 int err;
0034
0035 static int callback(__u32 index, void *data)
0036 {
0037 struct callback_ctx *ctx = data;
0038
0039 if (index >= stop_index)
0040 return 1;
0041
0042 ctx->output += index;
0043
0044 return 0;
0045 }
0046
0047 static int empty_callback(__u32 index, void *data)
0048 {
0049 return 0;
0050 }
0051
0052 static int nested_callback2(__u32 index, void *data)
0053 {
0054 nr_loops_returned += bpf_loop(nested_callback_nr_loops, callback, data, 0);
0055
0056 return 0;
0057 }
0058
0059 static int nested_callback1(__u32 index, void *data)
0060 {
0061 bpf_loop(nested_callback_nr_loops, nested_callback2, data, 0);
0062 return 0;
0063 }
0064
0065 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0066 int test_prog(void *ctx)
0067 {
0068 struct callback_ctx data = {};
0069
0070 if (bpf_get_current_pid_tgid() >> 32 != pid)
0071 return 0;
0072
0073 nr_loops_returned = bpf_loop(nr_loops, callback, &data, 0);
0074
0075 if (nr_loops_returned < 0)
0076 err = nr_loops_returned;
0077 else
0078 g_output = data.output;
0079
0080 return 0;
0081 }
0082
0083 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0084 int prog_null_ctx(void *ctx)
0085 {
0086 if (bpf_get_current_pid_tgid() >> 32 != pid)
0087 return 0;
0088
0089 nr_loops_returned = bpf_loop(nr_loops, empty_callback, NULL, 0);
0090
0091 return 0;
0092 }
0093
0094 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0095 int prog_invalid_flags(void *ctx)
0096 {
0097 struct callback_ctx data = {};
0098
0099 if (bpf_get_current_pid_tgid() >> 32 != pid)
0100 return 0;
0101
0102 err = bpf_loop(nr_loops, callback, &data, 1);
0103
0104 return 0;
0105 }
0106
0107 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0108 int prog_nested_calls(void *ctx)
0109 {
0110 struct callback_ctx data = {};
0111
0112 if (bpf_get_current_pid_tgid() >> 32 != pid)
0113 return 0;
0114
0115 nr_loops_returned = 0;
0116 bpf_loop(nr_loops, nested_callback1, &data, 0);
0117
0118 g_output = data.output;
0119
0120 return 0;
0121 }
0122
0123 static int callback_set_f0(int i, void *ctx)
0124 {
0125 g_output = 0xF0;
0126 return 0;
0127 }
0128
0129 static int callback_set_0f(int i, void *ctx)
0130 {
0131 g_output = 0x0F;
0132 return 0;
0133 }
0134
0135
0136
0137
0138 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0139 int prog_non_constant_callback(void *ctx)
0140 {
0141 struct callback_ctx data = {};
0142
0143 if (bpf_get_current_pid_tgid() >> 32 != pid)
0144 return 0;
0145
0146 int (*callback)(int i, void *ctx);
0147
0148 g_output = 0;
0149
0150 if (callback_selector == 0x0F)
0151 callback = callback_set_0f;
0152 else
0153 callback = callback_set_f0;
0154
0155 bpf_loop(1, callback, NULL, 0);
0156
0157 return 0;
0158 }
0159
0160 static int stack_check_inner_callback(void *ctx)
0161 {
0162 return 0;
0163 }
0164
0165 static int map1_lookup_elem(int key)
0166 {
0167 int *val = bpf_map_lookup_elem(&map1, &key);
0168
0169 return val ? *val : -1;
0170 }
0171
0172 static void map1_update_elem(int key, int val)
0173 {
0174 bpf_map_update_elem(&map1, &key, &val, BPF_ANY);
0175 }
0176
0177 static int stack_check_outer_callback(void *ctx)
0178 {
0179 int a = map1_lookup_elem(1);
0180 int b = map1_lookup_elem(2);
0181 int c = map1_lookup_elem(3);
0182 int d = map1_lookup_elem(4);
0183 int e = map1_lookup_elem(5);
0184 int f = map1_lookup_elem(6);
0185
0186 bpf_loop(1, stack_check_inner_callback, NULL, 0);
0187
0188 map1_update_elem(1, a + 1);
0189 map1_update_elem(2, b + 1);
0190 map1_update_elem(3, c + 1);
0191 map1_update_elem(4, d + 1);
0192 map1_update_elem(5, e + 1);
0193 map1_update_elem(6, f + 1);
0194
0195 return 0;
0196 }
0197
0198
0199
0200
0201
0202
0203
0204 SEC("fentry/" SYS_PREFIX "sys_nanosleep")
0205 int stack_check(void *ctx)
0206 {
0207 if (bpf_get_current_pid_tgid() >> 32 != pid)
0208 return 0;
0209
0210 int a = map1_lookup_elem(7);
0211 int b = map1_lookup_elem(8);
0212 int c = map1_lookup_elem(9);
0213 int d = map1_lookup_elem(10);
0214 int e = map1_lookup_elem(11);
0215 int f = map1_lookup_elem(12);
0216
0217 bpf_loop(1, stack_check_outer_callback, NULL, 0);
0218
0219 map1_update_elem(7, a + 1);
0220 map1_update_elem(8, b + 1);
0221 map1_update_elem(9, c + 1);
0222 map1_update_elem(10, d + 1);
0223 map1_update_elem(11, e + 1);
0224 map1_update_elem(12, f + 1);
0225
0226 return 0;
0227 }