1*300f19dcSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
2*300f19dcSKumar Kartikeya Dwivedi #include <vmlinux.h>
3*300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h>
4*300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h>
5*300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_core_read.h>
6*300f19dcSKumar Kartikeya Dwivedi #include "bpf_experimental.h"
7*300f19dcSKumar Kartikeya Dwivedi 
8*300f19dcSKumar Kartikeya Dwivedi #include "linked_list.h"
9*300f19dcSKumar Kartikeya Dwivedi 
10*300f19dcSKumar Kartikeya Dwivedi #define INIT                                                  \
11*300f19dcSKumar Kartikeya Dwivedi 	struct map_value *v, *v2, *iv, *iv2;                  \
12*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f, *f1, *f2;                              \
13*300f19dcSKumar Kartikeya Dwivedi 	struct bar *b;                                        \
14*300f19dcSKumar Kartikeya Dwivedi 	void *map;                                            \
15*300f19dcSKumar Kartikeya Dwivedi                                                               \
16*300f19dcSKumar Kartikeya Dwivedi 	map = bpf_map_lookup_elem(&map_of_maps, &(int){ 0 }); \
17*300f19dcSKumar Kartikeya Dwivedi 	if (!map)                                             \
18*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
19*300f19dcSKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &(int){ 0 });     \
20*300f19dcSKumar Kartikeya Dwivedi 	if (!v)                                               \
21*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
22*300f19dcSKumar Kartikeya Dwivedi 	v2 = bpf_map_lookup_elem(&array_map, &(int){ 0 });    \
23*300f19dcSKumar Kartikeya Dwivedi 	if (!v2)                                              \
24*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
25*300f19dcSKumar Kartikeya Dwivedi 	iv = bpf_map_lookup_elem(map, &(int){ 0 });           \
26*300f19dcSKumar Kartikeya Dwivedi 	if (!iv)                                              \
27*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
28*300f19dcSKumar Kartikeya Dwivedi 	iv2 = bpf_map_lookup_elem(map, &(int){ 0 });          \
29*300f19dcSKumar Kartikeya Dwivedi 	if (!iv2)                                             \
30*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
31*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));                          \
32*300f19dcSKumar Kartikeya Dwivedi 	if (!f)                                               \
33*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
34*300f19dcSKumar Kartikeya Dwivedi 	f1 = f;                                               \
35*300f19dcSKumar Kartikeya Dwivedi 	f2 = bpf_obj_new(typeof(*f2));                        \
36*300f19dcSKumar Kartikeya Dwivedi 	if (!f2) {                                            \
37*300f19dcSKumar Kartikeya Dwivedi 		bpf_obj_drop(f1);                             \
38*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
39*300f19dcSKumar Kartikeya Dwivedi 	}                                                     \
40*300f19dcSKumar Kartikeya Dwivedi 	b = bpf_obj_new(typeof(*b));                          \
41*300f19dcSKumar Kartikeya Dwivedi 	if (!b) {                                             \
42*300f19dcSKumar Kartikeya Dwivedi 		bpf_obj_drop(f2);                             \
43*300f19dcSKumar Kartikeya Dwivedi 		bpf_obj_drop(f1);                             \
44*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                     \
45*300f19dcSKumar Kartikeya Dwivedi 	}
46*300f19dcSKumar Kartikeya Dwivedi 
47*300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, hexpr)                              \
48*300f19dcSKumar Kartikeya Dwivedi 	SEC("?tc")                                          \
49*300f19dcSKumar Kartikeya Dwivedi 	int test##_missing_lock_##op(void *ctx)             \
50*300f19dcSKumar Kartikeya Dwivedi 	{                                                   \
51*300f19dcSKumar Kartikeya Dwivedi 		INIT;                                       \
52*300f19dcSKumar Kartikeya Dwivedi 		void (*p)(void *) = (void *)&bpf_list_##op; \
53*300f19dcSKumar Kartikeya Dwivedi 		p(hexpr);                                   \
54*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                   \
55*300f19dcSKumar Kartikeya Dwivedi 	}
56*300f19dcSKumar Kartikeya Dwivedi 
57*300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, push_front, &f->head);
58*300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, push_back, &f->head);
59*300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_front, &f->head);
60*300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_back, &f->head);
61*300f19dcSKumar Kartikeya Dwivedi 
62*300f19dcSKumar Kartikeya Dwivedi CHECK(global, push_front, &ghead);
63*300f19dcSKumar Kartikeya Dwivedi CHECK(global, push_back, &ghead);
64*300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_front, &ghead);
65*300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_back, &ghead);
66*300f19dcSKumar Kartikeya Dwivedi 
67*300f19dcSKumar Kartikeya Dwivedi CHECK(map, push_front, &v->head);
68*300f19dcSKumar Kartikeya Dwivedi CHECK(map, push_back, &v->head);
69*300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_front, &v->head);
70*300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_back, &v->head);
71*300f19dcSKumar Kartikeya Dwivedi 
72*300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, push_front, &iv->head);
73*300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, push_back, &iv->head);
74*300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_front, &iv->head);
75*300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_back, &iv->head);
76*300f19dcSKumar Kartikeya Dwivedi 
77*300f19dcSKumar Kartikeya Dwivedi #undef CHECK
78*300f19dcSKumar Kartikeya Dwivedi 
79*300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, lexpr, hexpr)                       \
80*300f19dcSKumar Kartikeya Dwivedi 	SEC("?tc")                                          \
81*300f19dcSKumar Kartikeya Dwivedi 	int test##_incorrect_lock_##op(void *ctx)           \
82*300f19dcSKumar Kartikeya Dwivedi 	{                                                   \
83*300f19dcSKumar Kartikeya Dwivedi 		INIT;                                       \
84*300f19dcSKumar Kartikeya Dwivedi 		void (*p)(void *) = (void *)&bpf_list_##op; \
85*300f19dcSKumar Kartikeya Dwivedi 		bpf_spin_lock(lexpr);                       \
86*300f19dcSKumar Kartikeya Dwivedi 		p(hexpr);                                   \
87*300f19dcSKumar Kartikeya Dwivedi 		return 0;                                   \
88*300f19dcSKumar Kartikeya Dwivedi 	}
89*300f19dcSKumar Kartikeya Dwivedi 
90*300f19dcSKumar Kartikeya Dwivedi #define CHECK_OP(op)                                           \
91*300f19dcSKumar Kartikeya Dwivedi 	CHECK(kptr_kptr, op, &f1->lock, &f2->head);            \
92*300f19dcSKumar Kartikeya Dwivedi 	CHECK(kptr_global, op, &f1->lock, &ghead);             \
93*300f19dcSKumar Kartikeya Dwivedi 	CHECK(kptr_map, op, &f1->lock, &v->head);              \
94*300f19dcSKumar Kartikeya Dwivedi 	CHECK(kptr_inner_map, op, &f1->lock, &iv->head);       \
95*300f19dcSKumar Kartikeya Dwivedi                                                                \
96*300f19dcSKumar Kartikeya Dwivedi 	CHECK(global_global, op, &glock2, &ghead);             \
97*300f19dcSKumar Kartikeya Dwivedi 	CHECK(global_kptr, op, &glock, &f1->head);             \
98*300f19dcSKumar Kartikeya Dwivedi 	CHECK(global_map, op, &glock, &v->head);               \
99*300f19dcSKumar Kartikeya Dwivedi 	CHECK(global_inner_map, op, &glock, &iv->head);        \
100*300f19dcSKumar Kartikeya Dwivedi                                                                \
101*300f19dcSKumar Kartikeya Dwivedi 	CHECK(map_map, op, &v->lock, &v2->head);               \
102*300f19dcSKumar Kartikeya Dwivedi 	CHECK(map_kptr, op, &v->lock, &f2->head);              \
103*300f19dcSKumar Kartikeya Dwivedi 	CHECK(map_global, op, &v->lock, &ghead);               \
104*300f19dcSKumar Kartikeya Dwivedi 	CHECK(map_inner_map, op, &v->lock, &iv->head);         \
105*300f19dcSKumar Kartikeya Dwivedi                                                                \
106*300f19dcSKumar Kartikeya Dwivedi 	CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head); \
107*300f19dcSKumar Kartikeya Dwivedi 	CHECK(inner_map_kptr, op, &iv->lock, &f2->head);       \
108*300f19dcSKumar Kartikeya Dwivedi 	CHECK(inner_map_global, op, &iv->lock, &ghead);        \
109*300f19dcSKumar Kartikeya Dwivedi 	CHECK(inner_map_map, op, &iv->lock, &v->head);
110*300f19dcSKumar Kartikeya Dwivedi 
111*300f19dcSKumar Kartikeya Dwivedi CHECK_OP(push_front);
112*300f19dcSKumar Kartikeya Dwivedi CHECK_OP(push_back);
113*300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_front);
114*300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_back);
115*300f19dcSKumar Kartikeya Dwivedi 
116*300f19dcSKumar Kartikeya Dwivedi #undef CHECK
117*300f19dcSKumar Kartikeya Dwivedi #undef CHECK_OP
118*300f19dcSKumar Kartikeya Dwivedi #undef INIT
119*300f19dcSKumar Kartikeya Dwivedi 
120*300f19dcSKumar Kartikeya Dwivedi SEC("?kprobe/xyz")
121*300f19dcSKumar Kartikeya Dwivedi int map_compat_kprobe(void *ctx)
122*300f19dcSKumar Kartikeya Dwivedi {
123*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
124*300f19dcSKumar Kartikeya Dwivedi 	return 0;
125*300f19dcSKumar Kartikeya Dwivedi }
126*300f19dcSKumar Kartikeya Dwivedi 
127*300f19dcSKumar Kartikeya Dwivedi SEC("?kretprobe/xyz")
128*300f19dcSKumar Kartikeya Dwivedi int map_compat_kretprobe(void *ctx)
129*300f19dcSKumar Kartikeya Dwivedi {
130*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
131*300f19dcSKumar Kartikeya Dwivedi 	return 0;
132*300f19dcSKumar Kartikeya Dwivedi }
133*300f19dcSKumar Kartikeya Dwivedi 
134*300f19dcSKumar Kartikeya Dwivedi SEC("?tracepoint/xyz")
135*300f19dcSKumar Kartikeya Dwivedi int map_compat_tp(void *ctx)
136*300f19dcSKumar Kartikeya Dwivedi {
137*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
138*300f19dcSKumar Kartikeya Dwivedi 	return 0;
139*300f19dcSKumar Kartikeya Dwivedi }
140*300f19dcSKumar Kartikeya Dwivedi 
141*300f19dcSKumar Kartikeya Dwivedi SEC("?perf_event")
142*300f19dcSKumar Kartikeya Dwivedi int map_compat_perf(void *ctx)
143*300f19dcSKumar Kartikeya Dwivedi {
144*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
145*300f19dcSKumar Kartikeya Dwivedi 	return 0;
146*300f19dcSKumar Kartikeya Dwivedi }
147*300f19dcSKumar Kartikeya Dwivedi 
148*300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp/xyz")
149*300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp(void *ctx)
150*300f19dcSKumar Kartikeya Dwivedi {
151*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
152*300f19dcSKumar Kartikeya Dwivedi 	return 0;
153*300f19dcSKumar Kartikeya Dwivedi }
154*300f19dcSKumar Kartikeya Dwivedi 
155*300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp.w/xyz")
156*300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp_w(void *ctx)
157*300f19dcSKumar Kartikeya Dwivedi {
158*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, NULL);
159*300f19dcSKumar Kartikeya Dwivedi 	return 0;
160*300f19dcSKumar Kartikeya Dwivedi }
161*300f19dcSKumar Kartikeya Dwivedi 
162*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
163*300f19dcSKumar Kartikeya Dwivedi int obj_type_id_oor(void *ctx)
164*300f19dcSKumar Kartikeya Dwivedi {
165*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_new_impl(~0UL, NULL);
166*300f19dcSKumar Kartikeya Dwivedi 	return 0;
167*300f19dcSKumar Kartikeya Dwivedi }
168*300f19dcSKumar Kartikeya Dwivedi 
169*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
170*300f19dcSKumar Kartikeya Dwivedi int obj_new_no_composite(void *ctx)
171*300f19dcSKumar Kartikeya Dwivedi {
172*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_new_impl(bpf_core_type_id_local(int), (void *)42);
173*300f19dcSKumar Kartikeya Dwivedi 	return 0;
174*300f19dcSKumar Kartikeya Dwivedi }
175*300f19dcSKumar Kartikeya Dwivedi 
176*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
177*300f19dcSKumar Kartikeya Dwivedi int obj_new_no_struct(void *ctx)
178*300f19dcSKumar Kartikeya Dwivedi {
179*300f19dcSKumar Kartikeya Dwivedi 
180*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_new(union { int data; unsigned udata; });
181*300f19dcSKumar Kartikeya Dwivedi 	return 0;
182*300f19dcSKumar Kartikeya Dwivedi }
183*300f19dcSKumar Kartikeya Dwivedi 
184*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
185*300f19dcSKumar Kartikeya Dwivedi int obj_drop_non_zero_off(void *ctx)
186*300f19dcSKumar Kartikeya Dwivedi {
187*300f19dcSKumar Kartikeya Dwivedi 	void *f;
188*300f19dcSKumar Kartikeya Dwivedi 
189*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(struct foo);
190*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
191*300f19dcSKumar Kartikeya Dwivedi 		return 0;
192*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_drop(f+1);
193*300f19dcSKumar Kartikeya Dwivedi 	return 0;
194*300f19dcSKumar Kartikeya Dwivedi }
195*300f19dcSKumar Kartikeya Dwivedi 
196*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
197*300f19dcSKumar Kartikeya Dwivedi int new_null_ret(void *ctx)
198*300f19dcSKumar Kartikeya Dwivedi {
199*300f19dcSKumar Kartikeya Dwivedi 	return bpf_obj_new(struct foo)->data;
200*300f19dcSKumar Kartikeya Dwivedi }
201*300f19dcSKumar Kartikeya Dwivedi 
202*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
203*300f19dcSKumar Kartikeya Dwivedi int obj_new_acq(void *ctx)
204*300f19dcSKumar Kartikeya Dwivedi {
205*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_new(struct foo);
206*300f19dcSKumar Kartikeya Dwivedi 	return 0;
207*300f19dcSKumar Kartikeya Dwivedi }
208*300f19dcSKumar Kartikeya Dwivedi 
209*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
210*300f19dcSKumar Kartikeya Dwivedi int use_after_drop(void *ctx)
211*300f19dcSKumar Kartikeya Dwivedi {
212*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
213*300f19dcSKumar Kartikeya Dwivedi 
214*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
215*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
216*300f19dcSKumar Kartikeya Dwivedi 		return 0;
217*300f19dcSKumar Kartikeya Dwivedi 	bpf_obj_drop(f);
218*300f19dcSKumar Kartikeya Dwivedi 	return f->data;
219*300f19dcSKumar Kartikeya Dwivedi }
220*300f19dcSKumar Kartikeya Dwivedi 
221*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
222*300f19dcSKumar Kartikeya Dwivedi int ptr_walk_scalar(void *ctx)
223*300f19dcSKumar Kartikeya Dwivedi {
224*300f19dcSKumar Kartikeya Dwivedi 	struct test1 {
225*300f19dcSKumar Kartikeya Dwivedi 		struct test2 {
226*300f19dcSKumar Kartikeya Dwivedi 			struct test2 *next;
227*300f19dcSKumar Kartikeya Dwivedi 		} *ptr;
228*300f19dcSKumar Kartikeya Dwivedi 	} *p;
229*300f19dcSKumar Kartikeya Dwivedi 
230*300f19dcSKumar Kartikeya Dwivedi 	p = bpf_obj_new(typeof(*p));
231*300f19dcSKumar Kartikeya Dwivedi 	if (!p)
232*300f19dcSKumar Kartikeya Dwivedi 		return 0;
233*300f19dcSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(p->ptr);
234*300f19dcSKumar Kartikeya Dwivedi 	return 0;
235*300f19dcSKumar Kartikeya Dwivedi }
236*300f19dcSKumar Kartikeya Dwivedi 
237*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
238*300f19dcSKumar Kartikeya Dwivedi int direct_read_lock(void *ctx)
239*300f19dcSKumar Kartikeya Dwivedi {
240*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
241*300f19dcSKumar Kartikeya Dwivedi 
242*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
243*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
244*300f19dcSKumar Kartikeya Dwivedi 		return 0;
245*300f19dcSKumar Kartikeya Dwivedi 	return *(int *)&f->lock;
246*300f19dcSKumar Kartikeya Dwivedi }
247*300f19dcSKumar Kartikeya Dwivedi 
248*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
249*300f19dcSKumar Kartikeya Dwivedi int direct_write_lock(void *ctx)
250*300f19dcSKumar Kartikeya Dwivedi {
251*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
252*300f19dcSKumar Kartikeya Dwivedi 
253*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
254*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
255*300f19dcSKumar Kartikeya Dwivedi 		return 0;
256*300f19dcSKumar Kartikeya Dwivedi 	*(int *)&f->lock = 0;
257*300f19dcSKumar Kartikeya Dwivedi 	return 0;
258*300f19dcSKumar Kartikeya Dwivedi }
259*300f19dcSKumar Kartikeya Dwivedi 
260*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
261*300f19dcSKumar Kartikeya Dwivedi int direct_read_head(void *ctx)
262*300f19dcSKumar Kartikeya Dwivedi {
263*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
264*300f19dcSKumar Kartikeya Dwivedi 
265*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
266*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
267*300f19dcSKumar Kartikeya Dwivedi 		return 0;
268*300f19dcSKumar Kartikeya Dwivedi 	return *(int *)&f->head;
269*300f19dcSKumar Kartikeya Dwivedi }
270*300f19dcSKumar Kartikeya Dwivedi 
271*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
272*300f19dcSKumar Kartikeya Dwivedi int direct_write_head(void *ctx)
273*300f19dcSKumar Kartikeya Dwivedi {
274*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
275*300f19dcSKumar Kartikeya Dwivedi 
276*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
277*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
278*300f19dcSKumar Kartikeya Dwivedi 		return 0;
279*300f19dcSKumar Kartikeya Dwivedi 	*(int *)&f->head = 0;
280*300f19dcSKumar Kartikeya Dwivedi 	return 0;
281*300f19dcSKumar Kartikeya Dwivedi }
282*300f19dcSKumar Kartikeya Dwivedi 
283*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
284*300f19dcSKumar Kartikeya Dwivedi int direct_read_node(void *ctx)
285*300f19dcSKumar Kartikeya Dwivedi {
286*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
287*300f19dcSKumar Kartikeya Dwivedi 
288*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
289*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
290*300f19dcSKumar Kartikeya Dwivedi 		return 0;
291*300f19dcSKumar Kartikeya Dwivedi 	return *(int *)&f->node;
292*300f19dcSKumar Kartikeya Dwivedi }
293*300f19dcSKumar Kartikeya Dwivedi 
294*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
295*300f19dcSKumar Kartikeya Dwivedi int direct_write_node(void *ctx)
296*300f19dcSKumar Kartikeya Dwivedi {
297*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
298*300f19dcSKumar Kartikeya Dwivedi 
299*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
300*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
301*300f19dcSKumar Kartikeya Dwivedi 		return 0;
302*300f19dcSKumar Kartikeya Dwivedi 	*(int *)&f->node = 0;
303*300f19dcSKumar Kartikeya Dwivedi 	return 0;
304*300f19dcSKumar Kartikeya Dwivedi }
305*300f19dcSKumar Kartikeya Dwivedi 
306*300f19dcSKumar Kartikeya Dwivedi static __always_inline
307*300f19dcSKumar Kartikeya Dwivedi int write_after_op(void (*push_op)(void *head, void *node))
308*300f19dcSKumar Kartikeya Dwivedi {
309*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
310*300f19dcSKumar Kartikeya Dwivedi 
311*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
312*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
313*300f19dcSKumar Kartikeya Dwivedi 		return 0;
314*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
315*300f19dcSKumar Kartikeya Dwivedi 	push_op(&ghead, &f->node);
316*300f19dcSKumar Kartikeya Dwivedi 	f->data = 42;
317*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
318*300f19dcSKumar Kartikeya Dwivedi 
319*300f19dcSKumar Kartikeya Dwivedi 	return 0;
320*300f19dcSKumar Kartikeya Dwivedi }
321*300f19dcSKumar Kartikeya Dwivedi 
322*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
323*300f19dcSKumar Kartikeya Dwivedi int write_after_push_front(void *ctx)
324*300f19dcSKumar Kartikeya Dwivedi {
325*300f19dcSKumar Kartikeya Dwivedi 	return write_after_op((void *)bpf_list_push_front);
326*300f19dcSKumar Kartikeya Dwivedi }
327*300f19dcSKumar Kartikeya Dwivedi 
328*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
329*300f19dcSKumar Kartikeya Dwivedi int write_after_push_back(void *ctx)
330*300f19dcSKumar Kartikeya Dwivedi {
331*300f19dcSKumar Kartikeya Dwivedi 	return write_after_op((void *)bpf_list_push_back);
332*300f19dcSKumar Kartikeya Dwivedi }
333*300f19dcSKumar Kartikeya Dwivedi 
334*300f19dcSKumar Kartikeya Dwivedi static __always_inline
335*300f19dcSKumar Kartikeya Dwivedi int use_after_unlock(void (*op)(void *head, void *node))
336*300f19dcSKumar Kartikeya Dwivedi {
337*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
338*300f19dcSKumar Kartikeya Dwivedi 
339*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
340*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
341*300f19dcSKumar Kartikeya Dwivedi 		return 0;
342*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
343*300f19dcSKumar Kartikeya Dwivedi 	f->data = 42;
344*300f19dcSKumar Kartikeya Dwivedi 	op(&ghead, &f->node);
345*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
346*300f19dcSKumar Kartikeya Dwivedi 
347*300f19dcSKumar Kartikeya Dwivedi 	return f->data;
348*300f19dcSKumar Kartikeya Dwivedi }
349*300f19dcSKumar Kartikeya Dwivedi 
350*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
351*300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_front(void *ctx)
352*300f19dcSKumar Kartikeya Dwivedi {
353*300f19dcSKumar Kartikeya Dwivedi 	return use_after_unlock((void *)bpf_list_push_front);
354*300f19dcSKumar Kartikeya Dwivedi }
355*300f19dcSKumar Kartikeya Dwivedi 
356*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
357*300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_back(void *ctx)
358*300f19dcSKumar Kartikeya Dwivedi {
359*300f19dcSKumar Kartikeya Dwivedi 	return use_after_unlock((void *)bpf_list_push_back);
360*300f19dcSKumar Kartikeya Dwivedi }
361*300f19dcSKumar Kartikeya Dwivedi 
362*300f19dcSKumar Kartikeya Dwivedi static __always_inline
363*300f19dcSKumar Kartikeya Dwivedi int list_double_add(void (*op)(void *head, void *node))
364*300f19dcSKumar Kartikeya Dwivedi {
365*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
366*300f19dcSKumar Kartikeya Dwivedi 
367*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
368*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
369*300f19dcSKumar Kartikeya Dwivedi 		return 0;
370*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
371*300f19dcSKumar Kartikeya Dwivedi 	op(&ghead, &f->node);
372*300f19dcSKumar Kartikeya Dwivedi 	op(&ghead, &f->node);
373*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
374*300f19dcSKumar Kartikeya Dwivedi 
375*300f19dcSKumar Kartikeya Dwivedi 	return 0;
376*300f19dcSKumar Kartikeya Dwivedi }
377*300f19dcSKumar Kartikeya Dwivedi 
378*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
379*300f19dcSKumar Kartikeya Dwivedi int double_push_front(void *ctx)
380*300f19dcSKumar Kartikeya Dwivedi {
381*300f19dcSKumar Kartikeya Dwivedi 	return list_double_add((void *)bpf_list_push_front);
382*300f19dcSKumar Kartikeya Dwivedi }
383*300f19dcSKumar Kartikeya Dwivedi 
384*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
385*300f19dcSKumar Kartikeya Dwivedi int double_push_back(void *ctx)
386*300f19dcSKumar Kartikeya Dwivedi {
387*300f19dcSKumar Kartikeya Dwivedi 	return list_double_add((void *)bpf_list_push_back);
388*300f19dcSKumar Kartikeya Dwivedi }
389*300f19dcSKumar Kartikeya Dwivedi 
390*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
391*300f19dcSKumar Kartikeya Dwivedi int no_node_value_type(void *ctx)
392*300f19dcSKumar Kartikeya Dwivedi {
393*300f19dcSKumar Kartikeya Dwivedi 	void *p;
394*300f19dcSKumar Kartikeya Dwivedi 
395*300f19dcSKumar Kartikeya Dwivedi 	p = bpf_obj_new(struct { int data; });
396*300f19dcSKumar Kartikeya Dwivedi 	if (!p)
397*300f19dcSKumar Kartikeya Dwivedi 		return 0;
398*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
399*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, p);
400*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
401*300f19dcSKumar Kartikeya Dwivedi 
402*300f19dcSKumar Kartikeya Dwivedi 	return 0;
403*300f19dcSKumar Kartikeya Dwivedi }
404*300f19dcSKumar Kartikeya Dwivedi 
405*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
406*300f19dcSKumar Kartikeya Dwivedi int incorrect_value_type(void *ctx)
407*300f19dcSKumar Kartikeya Dwivedi {
408*300f19dcSKumar Kartikeya Dwivedi 	struct bar *b;
409*300f19dcSKumar Kartikeya Dwivedi 
410*300f19dcSKumar Kartikeya Dwivedi 	b = bpf_obj_new(typeof(*b));
411*300f19dcSKumar Kartikeya Dwivedi 	if (!b)
412*300f19dcSKumar Kartikeya Dwivedi 		return 0;
413*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
414*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, &b->node);
415*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
416*300f19dcSKumar Kartikeya Dwivedi 
417*300f19dcSKumar Kartikeya Dwivedi 	return 0;
418*300f19dcSKumar Kartikeya Dwivedi }
419*300f19dcSKumar Kartikeya Dwivedi 
420*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
421*300f19dcSKumar Kartikeya Dwivedi int incorrect_node_var_off(struct __sk_buff *ctx)
422*300f19dcSKumar Kartikeya Dwivedi {
423*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
424*300f19dcSKumar Kartikeya Dwivedi 
425*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
426*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
427*300f19dcSKumar Kartikeya Dwivedi 		return 0;
428*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
429*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, (void *)&f->node + ctx->protocol);
430*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
431*300f19dcSKumar Kartikeya Dwivedi 
432*300f19dcSKumar Kartikeya Dwivedi 	return 0;
433*300f19dcSKumar Kartikeya Dwivedi }
434*300f19dcSKumar Kartikeya Dwivedi 
435*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
436*300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off1(void *ctx)
437*300f19dcSKumar Kartikeya Dwivedi {
438*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
439*300f19dcSKumar Kartikeya Dwivedi 
440*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
441*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
442*300f19dcSKumar Kartikeya Dwivedi 		return 0;
443*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
444*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, (void *)&f->node + 1);
445*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
446*300f19dcSKumar Kartikeya Dwivedi 
447*300f19dcSKumar Kartikeya Dwivedi 	return 0;
448*300f19dcSKumar Kartikeya Dwivedi }
449*300f19dcSKumar Kartikeya Dwivedi 
450*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
451*300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off2(void *ctx)
452*300f19dcSKumar Kartikeya Dwivedi {
453*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
454*300f19dcSKumar Kartikeya Dwivedi 
455*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
456*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
457*300f19dcSKumar Kartikeya Dwivedi 		return 0;
458*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
459*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(&ghead, &f->node2);
460*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
461*300f19dcSKumar Kartikeya Dwivedi 
462*300f19dcSKumar Kartikeya Dwivedi 	return 0;
463*300f19dcSKumar Kartikeya Dwivedi }
464*300f19dcSKumar Kartikeya Dwivedi 
465*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
466*300f19dcSKumar Kartikeya Dwivedi int no_head_type(void *ctx)
467*300f19dcSKumar Kartikeya Dwivedi {
468*300f19dcSKumar Kartikeya Dwivedi 	void *p;
469*300f19dcSKumar Kartikeya Dwivedi 
470*300f19dcSKumar Kartikeya Dwivedi 	p = bpf_obj_new(typeof(struct { int data; }));
471*300f19dcSKumar Kartikeya Dwivedi 	if (!p)
472*300f19dcSKumar Kartikeya Dwivedi 		return 0;
473*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
474*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front(p, NULL);
475*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
476*300f19dcSKumar Kartikeya Dwivedi 
477*300f19dcSKumar Kartikeya Dwivedi 	return 0;
478*300f19dcSKumar Kartikeya Dwivedi }
479*300f19dcSKumar Kartikeya Dwivedi 
480*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
481*300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off1(struct __sk_buff *ctx)
482*300f19dcSKumar Kartikeya Dwivedi {
483*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
484*300f19dcSKumar Kartikeya Dwivedi 
485*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
486*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
487*300f19dcSKumar Kartikeya Dwivedi 		return 0;
488*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
489*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front((void *)&ghead + ctx->protocol, &f->node);
490*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
491*300f19dcSKumar Kartikeya Dwivedi 
492*300f19dcSKumar Kartikeya Dwivedi 	return 0;
493*300f19dcSKumar Kartikeya Dwivedi }
494*300f19dcSKumar Kartikeya Dwivedi 
495*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
496*300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off2(struct __sk_buff *ctx)
497*300f19dcSKumar Kartikeya Dwivedi {
498*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
499*300f19dcSKumar Kartikeya Dwivedi 
500*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
501*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
502*300f19dcSKumar Kartikeya Dwivedi 		return 0;
503*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
504*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front((void *)&f->head + ctx->protocol, &f->node);
505*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
506*300f19dcSKumar Kartikeya Dwivedi 
507*300f19dcSKumar Kartikeya Dwivedi 	return 0;
508*300f19dcSKumar Kartikeya Dwivedi }
509*300f19dcSKumar Kartikeya Dwivedi 
510*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
511*300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off1(void *ctx)
512*300f19dcSKumar Kartikeya Dwivedi {
513*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
514*300f19dcSKumar Kartikeya Dwivedi 	struct bar *b;
515*300f19dcSKumar Kartikeya Dwivedi 
516*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
517*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
518*300f19dcSKumar Kartikeya Dwivedi 		return 0;
519*300f19dcSKumar Kartikeya Dwivedi 	b = bpf_obj_new(typeof(*b));
520*300f19dcSKumar Kartikeya Dwivedi 	if (!b) {
521*300f19dcSKumar Kartikeya Dwivedi 		bpf_obj_drop(f);
522*300f19dcSKumar Kartikeya Dwivedi 		return 0;
523*300f19dcSKumar Kartikeya Dwivedi 	}
524*300f19dcSKumar Kartikeya Dwivedi 
525*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&f->lock);
526*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front((void *)&f->head + 1, &b->node);
527*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&f->lock);
528*300f19dcSKumar Kartikeya Dwivedi 
529*300f19dcSKumar Kartikeya Dwivedi 	return 0;
530*300f19dcSKumar Kartikeya Dwivedi }
531*300f19dcSKumar Kartikeya Dwivedi 
532*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
533*300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off2(void *ctx)
534*300f19dcSKumar Kartikeya Dwivedi {
535*300f19dcSKumar Kartikeya Dwivedi 	struct foo *f;
536*300f19dcSKumar Kartikeya Dwivedi 	struct bar *b;
537*300f19dcSKumar Kartikeya Dwivedi 
538*300f19dcSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
539*300f19dcSKumar Kartikeya Dwivedi 	if (!f)
540*300f19dcSKumar Kartikeya Dwivedi 		return 0;
541*300f19dcSKumar Kartikeya Dwivedi 
542*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&glock);
543*300f19dcSKumar Kartikeya Dwivedi 	bpf_list_push_front((void *)&ghead + 1, &f->node);
544*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&glock);
545*300f19dcSKumar Kartikeya Dwivedi 
546*300f19dcSKumar Kartikeya Dwivedi 	return 0;
547*300f19dcSKumar Kartikeya Dwivedi }
548*300f19dcSKumar Kartikeya Dwivedi 
549*300f19dcSKumar Kartikeya Dwivedi static __always_inline
550*300f19dcSKumar Kartikeya Dwivedi int pop_ptr_off(void *(*op)(void *head))
551*300f19dcSKumar Kartikeya Dwivedi {
552*300f19dcSKumar Kartikeya Dwivedi 	struct {
553*300f19dcSKumar Kartikeya Dwivedi 		struct bpf_list_head head __contains(foo, node2);
554*300f19dcSKumar Kartikeya Dwivedi 		struct bpf_spin_lock lock;
555*300f19dcSKumar Kartikeya Dwivedi 	} *p;
556*300f19dcSKumar Kartikeya Dwivedi 	struct bpf_list_node *n;
557*300f19dcSKumar Kartikeya Dwivedi 
558*300f19dcSKumar Kartikeya Dwivedi 	p = bpf_obj_new(typeof(*p));
559*300f19dcSKumar Kartikeya Dwivedi 	if (!p)
560*300f19dcSKumar Kartikeya Dwivedi 		return 0;
561*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_lock(&p->lock);
562*300f19dcSKumar Kartikeya Dwivedi 	n = op(&p->head);
563*300f19dcSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&p->lock);
564*300f19dcSKumar Kartikeya Dwivedi 
565*300f19dcSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(n);
566*300f19dcSKumar Kartikeya Dwivedi 	return 0;
567*300f19dcSKumar Kartikeya Dwivedi }
568*300f19dcSKumar Kartikeya Dwivedi 
569*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
570*300f19dcSKumar Kartikeya Dwivedi int pop_front_off(void *ctx)
571*300f19dcSKumar Kartikeya Dwivedi {
572*300f19dcSKumar Kartikeya Dwivedi 	return pop_ptr_off((void *)bpf_list_pop_front);
573*300f19dcSKumar Kartikeya Dwivedi }
574*300f19dcSKumar Kartikeya Dwivedi 
575*300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
576*300f19dcSKumar Kartikeya Dwivedi int pop_back_off(void *ctx)
577*300f19dcSKumar Kartikeya Dwivedi {
578*300f19dcSKumar Kartikeya Dwivedi 	return pop_ptr_off((void *)bpf_list_pop_back);
579*300f19dcSKumar Kartikeya Dwivedi }
580*300f19dcSKumar Kartikeya Dwivedi 
581*300f19dcSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
582