1300f19dcSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0 2300f19dcSKumar Kartikeya Dwivedi #include <vmlinux.h> 3300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h> 4300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h> 5300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_core_read.h> 6300f19dcSKumar Kartikeya Dwivedi #include "bpf_experimental.h" 7300f19dcSKumar Kartikeya Dwivedi 8300f19dcSKumar Kartikeya Dwivedi #include "linked_list.h" 9300f19dcSKumar Kartikeya Dwivedi 10300f19dcSKumar Kartikeya Dwivedi #define INIT \ 11300f19dcSKumar Kartikeya Dwivedi struct map_value *v, *v2, *iv, *iv2; \ 12300f19dcSKumar Kartikeya Dwivedi struct foo *f, *f1, *f2; \ 13300f19dcSKumar Kartikeya Dwivedi struct bar *b; \ 14300f19dcSKumar Kartikeya Dwivedi void *map; \ 15300f19dcSKumar Kartikeya Dwivedi \ 16300f19dcSKumar Kartikeya Dwivedi map = bpf_map_lookup_elem(&map_of_maps, &(int){ 0 }); \ 17300f19dcSKumar Kartikeya Dwivedi if (!map) \ 18300f19dcSKumar Kartikeya Dwivedi return 0; \ 19300f19dcSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &(int){ 0 }); \ 20300f19dcSKumar Kartikeya Dwivedi if (!v) \ 21300f19dcSKumar Kartikeya Dwivedi return 0; \ 22300f19dcSKumar Kartikeya Dwivedi v2 = bpf_map_lookup_elem(&array_map, &(int){ 0 }); \ 23300f19dcSKumar Kartikeya Dwivedi if (!v2) \ 24300f19dcSKumar Kartikeya Dwivedi return 0; \ 25300f19dcSKumar Kartikeya Dwivedi iv = bpf_map_lookup_elem(map, &(int){ 0 }); \ 26300f19dcSKumar Kartikeya Dwivedi if (!iv) \ 27300f19dcSKumar Kartikeya Dwivedi return 0; \ 28300f19dcSKumar Kartikeya Dwivedi iv2 = bpf_map_lookup_elem(map, &(int){ 0 }); \ 29300f19dcSKumar Kartikeya Dwivedi if (!iv2) \ 30300f19dcSKumar Kartikeya Dwivedi return 0; \ 31300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); \ 32300f19dcSKumar Kartikeya Dwivedi if (!f) \ 33300f19dcSKumar Kartikeya Dwivedi return 0; \ 34300f19dcSKumar Kartikeya Dwivedi f1 = f; \ 35300f19dcSKumar Kartikeya Dwivedi f2 = bpf_obj_new(typeof(*f2)); \ 36300f19dcSKumar Kartikeya Dwivedi if (!f2) { \ 37300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f1); \ 38300f19dcSKumar Kartikeya Dwivedi return 0; \ 39300f19dcSKumar Kartikeya Dwivedi } \ 40300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); \ 41300f19dcSKumar Kartikeya Dwivedi if (!b) { \ 42300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f2); \ 43300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f1); \ 44300f19dcSKumar Kartikeya Dwivedi return 0; \ 45300f19dcSKumar Kartikeya Dwivedi } 46300f19dcSKumar Kartikeya Dwivedi 47300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, hexpr) \ 48300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \ 49300f19dcSKumar Kartikeya Dwivedi int test##_missing_lock_##op(void *ctx) \ 50300f19dcSKumar Kartikeya Dwivedi { \ 51300f19dcSKumar Kartikeya Dwivedi INIT; \ 52300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \ 53300f19dcSKumar Kartikeya Dwivedi p(hexpr); \ 54300f19dcSKumar Kartikeya Dwivedi return 0; \ 55300f19dcSKumar Kartikeya Dwivedi } 56300f19dcSKumar Kartikeya Dwivedi 57300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_front, &f->head); 58300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_back, &f->head); 59300f19dcSKumar Kartikeya Dwivedi 60300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_front, &ghead); 61300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_back, &ghead); 62300f19dcSKumar Kartikeya Dwivedi 63300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_front, &v->head); 64300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_back, &v->head); 65300f19dcSKumar Kartikeya Dwivedi 66300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_front, &iv->head); 67300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_back, &iv->head); 68300f19dcSKumar Kartikeya Dwivedi 69300f19dcSKumar Kartikeya Dwivedi #undef CHECK 70300f19dcSKumar Kartikeya Dwivedi 71*6a3cd331SDave Marchevsky #define CHECK(test, op, hexpr, nexpr) \ 72*6a3cd331SDave Marchevsky SEC("?tc") \ 73*6a3cd331SDave Marchevsky int test##_missing_lock_##op(void *ctx) \ 74*6a3cd331SDave Marchevsky { \ 75*6a3cd331SDave Marchevsky INIT; \ 76*6a3cd331SDave Marchevsky void (*p)(void *, void *) = (void *)&bpf_list_##op; \ 77*6a3cd331SDave Marchevsky p(hexpr, nexpr); \ 78*6a3cd331SDave Marchevsky return 0; \ 79*6a3cd331SDave Marchevsky } 80*6a3cd331SDave Marchevsky 81*6a3cd331SDave Marchevsky CHECK(kptr, push_front, &f->head, b); 82*6a3cd331SDave Marchevsky CHECK(kptr, push_back, &f->head, b); 83*6a3cd331SDave Marchevsky 84*6a3cd331SDave Marchevsky CHECK(global, push_front, &ghead, f); 85*6a3cd331SDave Marchevsky CHECK(global, push_back, &ghead, f); 86*6a3cd331SDave Marchevsky 87*6a3cd331SDave Marchevsky CHECK(map, push_front, &v->head, f); 88*6a3cd331SDave Marchevsky CHECK(map, push_back, &v->head, f); 89*6a3cd331SDave Marchevsky 90*6a3cd331SDave Marchevsky CHECK(inner_map, push_front, &iv->head, f); 91*6a3cd331SDave Marchevsky CHECK(inner_map, push_back, &iv->head, f); 92*6a3cd331SDave Marchevsky 93*6a3cd331SDave Marchevsky #undef CHECK 94*6a3cd331SDave Marchevsky 95300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, lexpr, hexpr) \ 96300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \ 97300f19dcSKumar Kartikeya Dwivedi int test##_incorrect_lock_##op(void *ctx) \ 98300f19dcSKumar Kartikeya Dwivedi { \ 99300f19dcSKumar Kartikeya Dwivedi INIT; \ 100300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \ 101300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(lexpr); \ 102300f19dcSKumar Kartikeya Dwivedi p(hexpr); \ 103300f19dcSKumar Kartikeya Dwivedi return 0; \ 104300f19dcSKumar Kartikeya Dwivedi } 105300f19dcSKumar Kartikeya Dwivedi 106300f19dcSKumar Kartikeya Dwivedi #define CHECK_OP(op) \ 107300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_kptr, op, &f1->lock, &f2->head); \ 1080b2971a2SAlexei Starovoitov CHECK(kptr_global, op, &f1->lock, &ghead); \ 109300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_map, op, &f1->lock, &v->head); \ 110300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_inner_map, op, &f1->lock, &iv->head); \ 111300f19dcSKumar Kartikeya Dwivedi \ 1120b2971a2SAlexei Starovoitov CHECK(global_global, op, &glock2, &ghead); \ 1130b2971a2SAlexei Starovoitov CHECK(global_kptr, op, &glock, &f1->head); \ 1140b2971a2SAlexei Starovoitov CHECK(global_map, op, &glock, &v->head); \ 1150b2971a2SAlexei Starovoitov CHECK(global_inner_map, op, &glock, &iv->head); \ 1160b2971a2SAlexei Starovoitov \ 117300f19dcSKumar Kartikeya Dwivedi CHECK(map_map, op, &v->lock, &v2->head); \ 118300f19dcSKumar Kartikeya Dwivedi CHECK(map_kptr, op, &v->lock, &f2->head); \ 1190b2971a2SAlexei Starovoitov CHECK(map_global, op, &v->lock, &ghead); \ 120300f19dcSKumar Kartikeya Dwivedi CHECK(map_inner_map, op, &v->lock, &iv->head); \ 121300f19dcSKumar Kartikeya Dwivedi \ 122300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head); \ 123300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_kptr, op, &iv->lock, &f2->head); \ 1240b2971a2SAlexei Starovoitov CHECK(inner_map_global, op, &iv->lock, &ghead); \ 125300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_map, op, &iv->lock, &v->head); 126300f19dcSKumar Kartikeya Dwivedi 127300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_front); 128300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_back); 129300f19dcSKumar Kartikeya Dwivedi 130300f19dcSKumar Kartikeya Dwivedi #undef CHECK 131300f19dcSKumar Kartikeya Dwivedi #undef CHECK_OP 132*6a3cd331SDave Marchevsky 133*6a3cd331SDave Marchevsky #define CHECK(test, op, lexpr, hexpr, nexpr) \ 134*6a3cd331SDave Marchevsky SEC("?tc") \ 135*6a3cd331SDave Marchevsky int test##_incorrect_lock_##op(void *ctx) \ 136*6a3cd331SDave Marchevsky { \ 137*6a3cd331SDave Marchevsky INIT; \ 138*6a3cd331SDave Marchevsky void (*p)(void *, void*) = (void *)&bpf_list_##op; \ 139*6a3cd331SDave Marchevsky bpf_spin_lock(lexpr); \ 140*6a3cd331SDave Marchevsky p(hexpr, nexpr); \ 141*6a3cd331SDave Marchevsky return 0; \ 142*6a3cd331SDave Marchevsky } 143*6a3cd331SDave Marchevsky 144*6a3cd331SDave Marchevsky #define CHECK_OP(op) \ 145*6a3cd331SDave Marchevsky CHECK(kptr_kptr, op, &f1->lock, &f2->head, b); \ 146*6a3cd331SDave Marchevsky CHECK(kptr_global, op, &f1->lock, &ghead, f); \ 147*6a3cd331SDave Marchevsky CHECK(kptr_map, op, &f1->lock, &v->head, f); \ 148*6a3cd331SDave Marchevsky CHECK(kptr_inner_map, op, &f1->lock, &iv->head, f); \ 149*6a3cd331SDave Marchevsky \ 150*6a3cd331SDave Marchevsky CHECK(global_global, op, &glock2, &ghead, f); \ 151*6a3cd331SDave Marchevsky CHECK(global_kptr, op, &glock, &f1->head, b); \ 152*6a3cd331SDave Marchevsky CHECK(global_map, op, &glock, &v->head, f); \ 153*6a3cd331SDave Marchevsky CHECK(global_inner_map, op, &glock, &iv->head, f); \ 154*6a3cd331SDave Marchevsky \ 155*6a3cd331SDave Marchevsky CHECK(map_map, op, &v->lock, &v2->head, f); \ 156*6a3cd331SDave Marchevsky CHECK(map_kptr, op, &v->lock, &f2->head, b); \ 157*6a3cd331SDave Marchevsky CHECK(map_global, op, &v->lock, &ghead, f); \ 158*6a3cd331SDave Marchevsky CHECK(map_inner_map, op, &v->lock, &iv->head, f); \ 159*6a3cd331SDave Marchevsky \ 160*6a3cd331SDave Marchevsky CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head, f); \ 161*6a3cd331SDave Marchevsky CHECK(inner_map_kptr, op, &iv->lock, &f2->head, b); \ 162*6a3cd331SDave Marchevsky CHECK(inner_map_global, op, &iv->lock, &ghead, f); \ 163*6a3cd331SDave Marchevsky CHECK(inner_map_map, op, &iv->lock, &v->head, f); 164*6a3cd331SDave Marchevsky 165*6a3cd331SDave Marchevsky CHECK_OP(push_front); 166*6a3cd331SDave Marchevsky CHECK_OP(push_back); 167*6a3cd331SDave Marchevsky 168*6a3cd331SDave Marchevsky #undef CHECK 169*6a3cd331SDave Marchevsky #undef CHECK_OP 170300f19dcSKumar Kartikeya Dwivedi #undef INIT 171300f19dcSKumar Kartikeya Dwivedi 172300f19dcSKumar Kartikeya Dwivedi SEC("?kprobe/xyz") 173300f19dcSKumar Kartikeya Dwivedi int map_compat_kprobe(void *ctx) 174300f19dcSKumar Kartikeya Dwivedi { 175300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 176300f19dcSKumar Kartikeya Dwivedi return 0; 177300f19dcSKumar Kartikeya Dwivedi } 178300f19dcSKumar Kartikeya Dwivedi 179300f19dcSKumar Kartikeya Dwivedi SEC("?kretprobe/xyz") 180300f19dcSKumar Kartikeya Dwivedi int map_compat_kretprobe(void *ctx) 181300f19dcSKumar Kartikeya Dwivedi { 182300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 183300f19dcSKumar Kartikeya Dwivedi return 0; 184300f19dcSKumar Kartikeya Dwivedi } 185300f19dcSKumar Kartikeya Dwivedi 186300f19dcSKumar Kartikeya Dwivedi SEC("?tracepoint/xyz") 187300f19dcSKumar Kartikeya Dwivedi int map_compat_tp(void *ctx) 188300f19dcSKumar Kartikeya Dwivedi { 189300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 190300f19dcSKumar Kartikeya Dwivedi return 0; 191300f19dcSKumar Kartikeya Dwivedi } 192300f19dcSKumar Kartikeya Dwivedi 193300f19dcSKumar Kartikeya Dwivedi SEC("?perf_event") 194300f19dcSKumar Kartikeya Dwivedi int map_compat_perf(void *ctx) 195300f19dcSKumar Kartikeya Dwivedi { 196300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 197300f19dcSKumar Kartikeya Dwivedi return 0; 198300f19dcSKumar Kartikeya Dwivedi } 199300f19dcSKumar Kartikeya Dwivedi 200300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp/xyz") 201300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp(void *ctx) 202300f19dcSKumar Kartikeya Dwivedi { 203300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 204300f19dcSKumar Kartikeya Dwivedi return 0; 205300f19dcSKumar Kartikeya Dwivedi } 206300f19dcSKumar Kartikeya Dwivedi 207300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp.w/xyz") 208300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp_w(void *ctx) 209300f19dcSKumar Kartikeya Dwivedi { 210300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 211300f19dcSKumar Kartikeya Dwivedi return 0; 212300f19dcSKumar Kartikeya Dwivedi } 213300f19dcSKumar Kartikeya Dwivedi 214300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 215300f19dcSKumar Kartikeya Dwivedi int obj_type_id_oor(void *ctx) 216300f19dcSKumar Kartikeya Dwivedi { 217300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(~0UL, NULL); 218300f19dcSKumar Kartikeya Dwivedi return 0; 219300f19dcSKumar Kartikeya Dwivedi } 220300f19dcSKumar Kartikeya Dwivedi 221300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 222300f19dcSKumar Kartikeya Dwivedi int obj_new_no_composite(void *ctx) 223300f19dcSKumar Kartikeya Dwivedi { 224300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(bpf_core_type_id_local(int), (void *)42); 225300f19dcSKumar Kartikeya Dwivedi return 0; 226300f19dcSKumar Kartikeya Dwivedi } 227300f19dcSKumar Kartikeya Dwivedi 228300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 229300f19dcSKumar Kartikeya Dwivedi int obj_new_no_struct(void *ctx) 230300f19dcSKumar Kartikeya Dwivedi { 231300f19dcSKumar Kartikeya Dwivedi 232300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(union { int data; unsigned udata; }); 233300f19dcSKumar Kartikeya Dwivedi return 0; 234300f19dcSKumar Kartikeya Dwivedi } 235300f19dcSKumar Kartikeya Dwivedi 236300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 237300f19dcSKumar Kartikeya Dwivedi int obj_drop_non_zero_off(void *ctx) 238300f19dcSKumar Kartikeya Dwivedi { 239300f19dcSKumar Kartikeya Dwivedi void *f; 240300f19dcSKumar Kartikeya Dwivedi 241300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(struct foo); 242300f19dcSKumar Kartikeya Dwivedi if (!f) 243300f19dcSKumar Kartikeya Dwivedi return 0; 244300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f+1); 245300f19dcSKumar Kartikeya Dwivedi return 0; 246300f19dcSKumar Kartikeya Dwivedi } 247300f19dcSKumar Kartikeya Dwivedi 248300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 249300f19dcSKumar Kartikeya Dwivedi int new_null_ret(void *ctx) 250300f19dcSKumar Kartikeya Dwivedi { 251300f19dcSKumar Kartikeya Dwivedi return bpf_obj_new(struct foo)->data; 252300f19dcSKumar Kartikeya Dwivedi } 253300f19dcSKumar Kartikeya Dwivedi 254300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 255300f19dcSKumar Kartikeya Dwivedi int obj_new_acq(void *ctx) 256300f19dcSKumar Kartikeya Dwivedi { 257300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(struct foo); 258300f19dcSKumar Kartikeya Dwivedi return 0; 259300f19dcSKumar Kartikeya Dwivedi } 260300f19dcSKumar Kartikeya Dwivedi 261300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 262300f19dcSKumar Kartikeya Dwivedi int use_after_drop(void *ctx) 263300f19dcSKumar Kartikeya Dwivedi { 264300f19dcSKumar Kartikeya Dwivedi struct foo *f; 265300f19dcSKumar Kartikeya Dwivedi 266300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 267300f19dcSKumar Kartikeya Dwivedi if (!f) 268300f19dcSKumar Kartikeya Dwivedi return 0; 269300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 270300f19dcSKumar Kartikeya Dwivedi return f->data; 271300f19dcSKumar Kartikeya Dwivedi } 272300f19dcSKumar Kartikeya Dwivedi 273300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 274300f19dcSKumar Kartikeya Dwivedi int ptr_walk_scalar(void *ctx) 275300f19dcSKumar Kartikeya Dwivedi { 276300f19dcSKumar Kartikeya Dwivedi struct test1 { 277300f19dcSKumar Kartikeya Dwivedi struct test2 { 278300f19dcSKumar Kartikeya Dwivedi struct test2 *next; 279300f19dcSKumar Kartikeya Dwivedi } *ptr; 280300f19dcSKumar Kartikeya Dwivedi } *p; 281300f19dcSKumar Kartikeya Dwivedi 282300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 283300f19dcSKumar Kartikeya Dwivedi if (!p) 284300f19dcSKumar Kartikeya Dwivedi return 0; 285300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(p->ptr); 286300f19dcSKumar Kartikeya Dwivedi return 0; 287300f19dcSKumar Kartikeya Dwivedi } 288300f19dcSKumar Kartikeya Dwivedi 289300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 290300f19dcSKumar Kartikeya Dwivedi int direct_read_lock(void *ctx) 291300f19dcSKumar Kartikeya Dwivedi { 292300f19dcSKumar Kartikeya Dwivedi struct foo *f; 293300f19dcSKumar Kartikeya Dwivedi 294300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 295300f19dcSKumar Kartikeya Dwivedi if (!f) 296300f19dcSKumar Kartikeya Dwivedi return 0; 297300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->lock; 298300f19dcSKumar Kartikeya Dwivedi } 299300f19dcSKumar Kartikeya Dwivedi 300300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 301300f19dcSKumar Kartikeya Dwivedi int direct_write_lock(void *ctx) 302300f19dcSKumar Kartikeya Dwivedi { 303300f19dcSKumar Kartikeya Dwivedi struct foo *f; 304300f19dcSKumar Kartikeya Dwivedi 305300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 306300f19dcSKumar Kartikeya Dwivedi if (!f) 307300f19dcSKumar Kartikeya Dwivedi return 0; 308300f19dcSKumar Kartikeya Dwivedi *(int *)&f->lock = 0; 309300f19dcSKumar Kartikeya Dwivedi return 0; 310300f19dcSKumar Kartikeya Dwivedi } 311300f19dcSKumar Kartikeya Dwivedi 312300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 313300f19dcSKumar Kartikeya Dwivedi int direct_read_head(void *ctx) 314300f19dcSKumar Kartikeya Dwivedi { 315300f19dcSKumar Kartikeya Dwivedi struct foo *f; 316300f19dcSKumar Kartikeya Dwivedi 317300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 318300f19dcSKumar Kartikeya Dwivedi if (!f) 319300f19dcSKumar Kartikeya Dwivedi return 0; 320300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->head; 321300f19dcSKumar Kartikeya Dwivedi } 322300f19dcSKumar Kartikeya Dwivedi 323300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 324300f19dcSKumar Kartikeya Dwivedi int direct_write_head(void *ctx) 325300f19dcSKumar Kartikeya Dwivedi { 326300f19dcSKumar Kartikeya Dwivedi struct foo *f; 327300f19dcSKumar Kartikeya Dwivedi 328300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 329300f19dcSKumar Kartikeya Dwivedi if (!f) 330300f19dcSKumar Kartikeya Dwivedi return 0; 331300f19dcSKumar Kartikeya Dwivedi *(int *)&f->head = 0; 332300f19dcSKumar Kartikeya Dwivedi return 0; 333300f19dcSKumar Kartikeya Dwivedi } 334300f19dcSKumar Kartikeya Dwivedi 335300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 336300f19dcSKumar Kartikeya Dwivedi int direct_read_node(void *ctx) 337300f19dcSKumar Kartikeya Dwivedi { 338300f19dcSKumar Kartikeya Dwivedi struct foo *f; 339300f19dcSKumar Kartikeya Dwivedi 340300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 341300f19dcSKumar Kartikeya Dwivedi if (!f) 342300f19dcSKumar Kartikeya Dwivedi return 0; 343300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->node; 344300f19dcSKumar Kartikeya Dwivedi } 345300f19dcSKumar Kartikeya Dwivedi 346300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 347300f19dcSKumar Kartikeya Dwivedi int direct_write_node(void *ctx) 348300f19dcSKumar Kartikeya Dwivedi { 349300f19dcSKumar Kartikeya Dwivedi struct foo *f; 350300f19dcSKumar Kartikeya Dwivedi 351300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 352300f19dcSKumar Kartikeya Dwivedi if (!f) 353300f19dcSKumar Kartikeya Dwivedi return 0; 354300f19dcSKumar Kartikeya Dwivedi *(int *)&f->node = 0; 355300f19dcSKumar Kartikeya Dwivedi return 0; 356300f19dcSKumar Kartikeya Dwivedi } 357300f19dcSKumar Kartikeya Dwivedi 358300f19dcSKumar Kartikeya Dwivedi static __always_inline 359300f19dcSKumar Kartikeya Dwivedi int use_after_unlock(void (*op)(void *head, void *node)) 360300f19dcSKumar Kartikeya Dwivedi { 361300f19dcSKumar Kartikeya Dwivedi struct foo *f; 362300f19dcSKumar Kartikeya Dwivedi 363300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 364300f19dcSKumar Kartikeya Dwivedi if (!f) 365300f19dcSKumar Kartikeya Dwivedi return 0; 366300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 367300f19dcSKumar Kartikeya Dwivedi f->data = 42; 368300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 369300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 370300f19dcSKumar Kartikeya Dwivedi 371300f19dcSKumar Kartikeya Dwivedi return f->data; 372300f19dcSKumar Kartikeya Dwivedi } 373300f19dcSKumar Kartikeya Dwivedi 374300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 375300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_front(void *ctx) 376300f19dcSKumar Kartikeya Dwivedi { 377300f19dcSKumar Kartikeya Dwivedi return use_after_unlock((void *)bpf_list_push_front); 378300f19dcSKumar Kartikeya Dwivedi } 379300f19dcSKumar Kartikeya Dwivedi 380300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 381300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_back(void *ctx) 382300f19dcSKumar Kartikeya Dwivedi { 383300f19dcSKumar Kartikeya Dwivedi return use_after_unlock((void *)bpf_list_push_back); 384300f19dcSKumar Kartikeya Dwivedi } 385300f19dcSKumar Kartikeya Dwivedi 386300f19dcSKumar Kartikeya Dwivedi static __always_inline 387300f19dcSKumar Kartikeya Dwivedi int list_double_add(void (*op)(void *head, void *node)) 388300f19dcSKumar Kartikeya Dwivedi { 389300f19dcSKumar Kartikeya Dwivedi struct foo *f; 390300f19dcSKumar Kartikeya Dwivedi 391300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 392300f19dcSKumar Kartikeya Dwivedi if (!f) 393300f19dcSKumar Kartikeya Dwivedi return 0; 394300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 395300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 396300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 397300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 398300f19dcSKumar Kartikeya Dwivedi 399300f19dcSKumar Kartikeya Dwivedi return 0; 400300f19dcSKumar Kartikeya Dwivedi } 401300f19dcSKumar Kartikeya Dwivedi 402300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 403300f19dcSKumar Kartikeya Dwivedi int double_push_front(void *ctx) 404300f19dcSKumar Kartikeya Dwivedi { 405300f19dcSKumar Kartikeya Dwivedi return list_double_add((void *)bpf_list_push_front); 406300f19dcSKumar Kartikeya Dwivedi } 407300f19dcSKumar Kartikeya Dwivedi 408300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 409300f19dcSKumar Kartikeya Dwivedi int double_push_back(void *ctx) 410300f19dcSKumar Kartikeya Dwivedi { 411300f19dcSKumar Kartikeya Dwivedi return list_double_add((void *)bpf_list_push_back); 412300f19dcSKumar Kartikeya Dwivedi } 413300f19dcSKumar Kartikeya Dwivedi 414300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 415300f19dcSKumar Kartikeya Dwivedi int no_node_value_type(void *ctx) 416300f19dcSKumar Kartikeya Dwivedi { 417300f19dcSKumar Kartikeya Dwivedi void *p; 418300f19dcSKumar Kartikeya Dwivedi 419300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(struct { int data; }); 420300f19dcSKumar Kartikeya Dwivedi if (!p) 421300f19dcSKumar Kartikeya Dwivedi return 0; 422300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 423300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, p); 424300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 425300f19dcSKumar Kartikeya Dwivedi 426300f19dcSKumar Kartikeya Dwivedi return 0; 427300f19dcSKumar Kartikeya Dwivedi } 428300f19dcSKumar Kartikeya Dwivedi 429300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 430300f19dcSKumar Kartikeya Dwivedi int incorrect_value_type(void *ctx) 431300f19dcSKumar Kartikeya Dwivedi { 432300f19dcSKumar Kartikeya Dwivedi struct bar *b; 433300f19dcSKumar Kartikeya Dwivedi 434300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 435300f19dcSKumar Kartikeya Dwivedi if (!b) 436300f19dcSKumar Kartikeya Dwivedi return 0; 437300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 438300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &b->node); 439300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 440300f19dcSKumar Kartikeya Dwivedi 441300f19dcSKumar Kartikeya Dwivedi return 0; 442300f19dcSKumar Kartikeya Dwivedi } 443300f19dcSKumar Kartikeya Dwivedi 444300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 445300f19dcSKumar Kartikeya Dwivedi int incorrect_node_var_off(struct __sk_buff *ctx) 446300f19dcSKumar Kartikeya Dwivedi { 447300f19dcSKumar Kartikeya Dwivedi struct foo *f; 448300f19dcSKumar Kartikeya Dwivedi 449300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 450300f19dcSKumar Kartikeya Dwivedi if (!f) 451300f19dcSKumar Kartikeya Dwivedi return 0; 452300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 453300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, (void *)&f->node + ctx->protocol); 454300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 455300f19dcSKumar Kartikeya Dwivedi 456300f19dcSKumar Kartikeya Dwivedi return 0; 457300f19dcSKumar Kartikeya Dwivedi } 458300f19dcSKumar Kartikeya Dwivedi 459300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 460300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off1(void *ctx) 461300f19dcSKumar Kartikeya Dwivedi { 462300f19dcSKumar Kartikeya Dwivedi struct foo *f; 463300f19dcSKumar Kartikeya Dwivedi 464300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 465300f19dcSKumar Kartikeya Dwivedi if (!f) 466300f19dcSKumar Kartikeya Dwivedi return 0; 467300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 468300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, (void *)&f->node + 1); 469300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 470300f19dcSKumar Kartikeya Dwivedi 471300f19dcSKumar Kartikeya Dwivedi return 0; 472300f19dcSKumar Kartikeya Dwivedi } 473300f19dcSKumar Kartikeya Dwivedi 474300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 475300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off2(void *ctx) 476300f19dcSKumar Kartikeya Dwivedi { 477300f19dcSKumar Kartikeya Dwivedi struct foo *f; 478300f19dcSKumar Kartikeya Dwivedi 479300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 480300f19dcSKumar Kartikeya Dwivedi if (!f) 481300f19dcSKumar Kartikeya Dwivedi return 0; 482300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 483300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &f->node2); 484300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 485300f19dcSKumar Kartikeya Dwivedi 486300f19dcSKumar Kartikeya Dwivedi return 0; 487300f19dcSKumar Kartikeya Dwivedi } 488300f19dcSKumar Kartikeya Dwivedi 489300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 490300f19dcSKumar Kartikeya Dwivedi int no_head_type(void *ctx) 491300f19dcSKumar Kartikeya Dwivedi { 492300f19dcSKumar Kartikeya Dwivedi void *p; 493300f19dcSKumar Kartikeya Dwivedi 494300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(struct { int data; })); 495300f19dcSKumar Kartikeya Dwivedi if (!p) 496300f19dcSKumar Kartikeya Dwivedi return 0; 497300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 498300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(p, NULL); 499300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 500300f19dcSKumar Kartikeya Dwivedi 501300f19dcSKumar Kartikeya Dwivedi return 0; 502300f19dcSKumar Kartikeya Dwivedi } 503300f19dcSKumar Kartikeya Dwivedi 504300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 505300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off1(struct __sk_buff *ctx) 506300f19dcSKumar Kartikeya Dwivedi { 507300f19dcSKumar Kartikeya Dwivedi struct foo *f; 508300f19dcSKumar Kartikeya Dwivedi 509300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 510300f19dcSKumar Kartikeya Dwivedi if (!f) 511300f19dcSKumar Kartikeya Dwivedi return 0; 512300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 513300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&ghead + ctx->protocol, &f->node); 514300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 515300f19dcSKumar Kartikeya Dwivedi 516300f19dcSKumar Kartikeya Dwivedi return 0; 517300f19dcSKumar Kartikeya Dwivedi } 518300f19dcSKumar Kartikeya Dwivedi 519300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 520300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off2(struct __sk_buff *ctx) 521300f19dcSKumar Kartikeya Dwivedi { 522300f19dcSKumar Kartikeya Dwivedi struct foo *f; 523300f19dcSKumar Kartikeya Dwivedi 524300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 525300f19dcSKumar Kartikeya Dwivedi if (!f) 526300f19dcSKumar Kartikeya Dwivedi return 0; 527300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 528300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + ctx->protocol, &f->node); 529300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 530300f19dcSKumar Kartikeya Dwivedi 531300f19dcSKumar Kartikeya Dwivedi return 0; 532300f19dcSKumar Kartikeya Dwivedi } 533300f19dcSKumar Kartikeya Dwivedi 534300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 535300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off1(void *ctx) 536300f19dcSKumar Kartikeya Dwivedi { 537300f19dcSKumar Kartikeya Dwivedi struct foo *f; 538300f19dcSKumar Kartikeya Dwivedi struct bar *b; 539300f19dcSKumar Kartikeya Dwivedi 540300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 541300f19dcSKumar Kartikeya Dwivedi if (!f) 542300f19dcSKumar Kartikeya Dwivedi return 0; 543300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 544300f19dcSKumar Kartikeya Dwivedi if (!b) { 545300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 546300f19dcSKumar Kartikeya Dwivedi return 0; 547300f19dcSKumar Kartikeya Dwivedi } 548300f19dcSKumar Kartikeya Dwivedi 549300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&f->lock); 550300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + 1, &b->node); 551300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&f->lock); 552300f19dcSKumar Kartikeya Dwivedi 553300f19dcSKumar Kartikeya Dwivedi return 0; 554300f19dcSKumar Kartikeya Dwivedi } 555300f19dcSKumar Kartikeya Dwivedi 556300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 557300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off2(void *ctx) 558300f19dcSKumar Kartikeya Dwivedi { 559300f19dcSKumar Kartikeya Dwivedi struct foo *f; 560300f19dcSKumar Kartikeya Dwivedi struct bar *b; 561300f19dcSKumar Kartikeya Dwivedi 562300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 563300f19dcSKumar Kartikeya Dwivedi if (!f) 564300f19dcSKumar Kartikeya Dwivedi return 0; 565300f19dcSKumar Kartikeya Dwivedi 566300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 567300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&ghead + 1, &f->node); 568300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 569300f19dcSKumar Kartikeya Dwivedi 570300f19dcSKumar Kartikeya Dwivedi return 0; 571300f19dcSKumar Kartikeya Dwivedi } 572300f19dcSKumar Kartikeya Dwivedi 573300f19dcSKumar Kartikeya Dwivedi static __always_inline 574300f19dcSKumar Kartikeya Dwivedi int pop_ptr_off(void *(*op)(void *head)) 575300f19dcSKumar Kartikeya Dwivedi { 576300f19dcSKumar Kartikeya Dwivedi struct { 577300f19dcSKumar Kartikeya Dwivedi struct bpf_list_head head __contains(foo, node2); 578300f19dcSKumar Kartikeya Dwivedi struct bpf_spin_lock lock; 579300f19dcSKumar Kartikeya Dwivedi } *p; 580300f19dcSKumar Kartikeya Dwivedi struct bpf_list_node *n; 581300f19dcSKumar Kartikeya Dwivedi 582300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 583300f19dcSKumar Kartikeya Dwivedi if (!p) 584300f19dcSKumar Kartikeya Dwivedi return 0; 585300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&p->lock); 586300f19dcSKumar Kartikeya Dwivedi n = op(&p->head); 587300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&p->lock); 588300f19dcSKumar Kartikeya Dwivedi 589300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(n); 590300f19dcSKumar Kartikeya Dwivedi return 0; 591300f19dcSKumar Kartikeya Dwivedi } 592300f19dcSKumar Kartikeya Dwivedi 593300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 594300f19dcSKumar Kartikeya Dwivedi int pop_front_off(void *ctx) 595300f19dcSKumar Kartikeya Dwivedi { 596300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_front); 597300f19dcSKumar Kartikeya Dwivedi } 598300f19dcSKumar Kartikeya Dwivedi 599300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 600300f19dcSKumar Kartikeya Dwivedi int pop_back_off(void *ctx) 601300f19dcSKumar Kartikeya Dwivedi { 602300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_back); 603300f19dcSKumar Kartikeya Dwivedi } 604300f19dcSKumar Kartikeya Dwivedi 605300f19dcSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL"; 606