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