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 716a3cd331SDave Marchevsky #define CHECK(test, op, hexpr, nexpr) \ 726a3cd331SDave Marchevsky SEC("?tc") \ 736a3cd331SDave Marchevsky int test##_missing_lock_##op(void *ctx) \ 746a3cd331SDave Marchevsky { \ 756a3cd331SDave Marchevsky INIT; \ 76*de67ba39SDave Marchevsky bpf_list_##op(hexpr, nexpr); \ 776a3cd331SDave Marchevsky return 0; \ 786a3cd331SDave Marchevsky } 796a3cd331SDave Marchevsky 80*de67ba39SDave Marchevsky CHECK(kptr, push_front, &f->head, &b->node); 81*de67ba39SDave Marchevsky CHECK(kptr, push_back, &f->head, &b->node); 826a3cd331SDave Marchevsky 83*de67ba39SDave Marchevsky CHECK(global, push_front, &ghead, &f->node2); 84*de67ba39SDave Marchevsky CHECK(global, push_back, &ghead, &f->node2); 856a3cd331SDave Marchevsky 86*de67ba39SDave Marchevsky CHECK(map, push_front, &v->head, &f->node2); 87*de67ba39SDave Marchevsky CHECK(map, push_back, &v->head, &f->node2); 886a3cd331SDave Marchevsky 89*de67ba39SDave Marchevsky CHECK(inner_map, push_front, &iv->head, &f->node2); 90*de67ba39SDave Marchevsky CHECK(inner_map, push_back, &iv->head, &f->node2); 916a3cd331SDave Marchevsky 926a3cd331SDave Marchevsky #undef CHECK 936a3cd331SDave Marchevsky 94300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, lexpr, hexpr) \ 95300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \ 96300f19dcSKumar Kartikeya Dwivedi int test##_incorrect_lock_##op(void *ctx) \ 97300f19dcSKumar Kartikeya Dwivedi { \ 98300f19dcSKumar Kartikeya Dwivedi INIT; \ 99300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \ 100300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(lexpr); \ 101300f19dcSKumar Kartikeya Dwivedi p(hexpr); \ 102300f19dcSKumar Kartikeya Dwivedi return 0; \ 103300f19dcSKumar Kartikeya Dwivedi } 104300f19dcSKumar Kartikeya Dwivedi 105300f19dcSKumar Kartikeya Dwivedi #define CHECK_OP(op) \ 106300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_kptr, op, &f1->lock, &f2->head); \ 1070b2971a2SAlexei Starovoitov CHECK(kptr_global, op, &f1->lock, &ghead); \ 108300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_map, op, &f1->lock, &v->head); \ 109300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_inner_map, op, &f1->lock, &iv->head); \ 110300f19dcSKumar Kartikeya Dwivedi \ 1110b2971a2SAlexei Starovoitov CHECK(global_global, op, &glock2, &ghead); \ 1120b2971a2SAlexei Starovoitov CHECK(global_kptr, op, &glock, &f1->head); \ 1130b2971a2SAlexei Starovoitov CHECK(global_map, op, &glock, &v->head); \ 1140b2971a2SAlexei Starovoitov CHECK(global_inner_map, op, &glock, &iv->head); \ 1150b2971a2SAlexei Starovoitov \ 116300f19dcSKumar Kartikeya Dwivedi CHECK(map_map, op, &v->lock, &v2->head); \ 117300f19dcSKumar Kartikeya Dwivedi CHECK(map_kptr, op, &v->lock, &f2->head); \ 1180b2971a2SAlexei Starovoitov CHECK(map_global, op, &v->lock, &ghead); \ 119300f19dcSKumar Kartikeya Dwivedi CHECK(map_inner_map, op, &v->lock, &iv->head); \ 120300f19dcSKumar Kartikeya Dwivedi \ 121300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head); \ 122300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_kptr, op, &iv->lock, &f2->head); \ 1230b2971a2SAlexei Starovoitov CHECK(inner_map_global, op, &iv->lock, &ghead); \ 124300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_map, op, &iv->lock, &v->head); 125300f19dcSKumar Kartikeya Dwivedi 126300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_front); 127300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_back); 128300f19dcSKumar Kartikeya Dwivedi 129300f19dcSKumar Kartikeya Dwivedi #undef CHECK 130300f19dcSKumar Kartikeya Dwivedi #undef CHECK_OP 1316a3cd331SDave Marchevsky 1326a3cd331SDave Marchevsky #define CHECK(test, op, lexpr, hexpr, nexpr) \ 1336a3cd331SDave Marchevsky SEC("?tc") \ 1346a3cd331SDave Marchevsky int test##_incorrect_lock_##op(void *ctx) \ 1356a3cd331SDave Marchevsky { \ 1366a3cd331SDave Marchevsky INIT; \ 1376a3cd331SDave Marchevsky bpf_spin_lock(lexpr); \ 138*de67ba39SDave Marchevsky bpf_list_##op(hexpr, nexpr); \ 1396a3cd331SDave Marchevsky return 0; \ 1406a3cd331SDave Marchevsky } 1416a3cd331SDave Marchevsky 1426a3cd331SDave Marchevsky #define CHECK_OP(op) \ 143*de67ba39SDave Marchevsky CHECK(kptr_kptr, op, &f1->lock, &f2->head, &b->node); \ 144*de67ba39SDave Marchevsky CHECK(kptr_global, op, &f1->lock, &ghead, &f->node2); \ 145*de67ba39SDave Marchevsky CHECK(kptr_map, op, &f1->lock, &v->head, &f->node2); \ 146*de67ba39SDave Marchevsky CHECK(kptr_inner_map, op, &f1->lock, &iv->head, &f->node2); \ 1476a3cd331SDave Marchevsky \ 148*de67ba39SDave Marchevsky CHECK(global_global, op, &glock2, &ghead, &f->node2); \ 149*de67ba39SDave Marchevsky CHECK(global_kptr, op, &glock, &f1->head, &b->node); \ 150*de67ba39SDave Marchevsky CHECK(global_map, op, &glock, &v->head, &f->node2); \ 151*de67ba39SDave Marchevsky CHECK(global_inner_map, op, &glock, &iv->head, &f->node2); \ 1526a3cd331SDave Marchevsky \ 153*de67ba39SDave Marchevsky CHECK(map_map, op, &v->lock, &v2->head, &f->node2); \ 154*de67ba39SDave Marchevsky CHECK(map_kptr, op, &v->lock, &f2->head, &b->node); \ 155*de67ba39SDave Marchevsky CHECK(map_global, op, &v->lock, &ghead, &f->node2); \ 156*de67ba39SDave Marchevsky CHECK(map_inner_map, op, &v->lock, &iv->head, &f->node2); \ 1576a3cd331SDave Marchevsky \ 158*de67ba39SDave Marchevsky CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head, &f->node2);\ 159*de67ba39SDave Marchevsky CHECK(inner_map_kptr, op, &iv->lock, &f2->head, &b->node); \ 160*de67ba39SDave Marchevsky CHECK(inner_map_global, op, &iv->lock, &ghead, &f->node2); \ 161*de67ba39SDave Marchevsky CHECK(inner_map_map, op, &iv->lock, &v->head, &f->node2); 1626a3cd331SDave Marchevsky 1636a3cd331SDave Marchevsky CHECK_OP(push_front); 1646a3cd331SDave Marchevsky CHECK_OP(push_back); 1656a3cd331SDave Marchevsky 1666a3cd331SDave Marchevsky #undef CHECK 1676a3cd331SDave Marchevsky #undef CHECK_OP 168300f19dcSKumar Kartikeya Dwivedi #undef INIT 169300f19dcSKumar Kartikeya Dwivedi 170300f19dcSKumar Kartikeya Dwivedi SEC("?kprobe/xyz") 171300f19dcSKumar Kartikeya Dwivedi int map_compat_kprobe(void *ctx) 172300f19dcSKumar Kartikeya Dwivedi { 173300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 174300f19dcSKumar Kartikeya Dwivedi return 0; 175300f19dcSKumar Kartikeya Dwivedi } 176300f19dcSKumar Kartikeya Dwivedi 177300f19dcSKumar Kartikeya Dwivedi SEC("?kretprobe/xyz") 178300f19dcSKumar Kartikeya Dwivedi int map_compat_kretprobe(void *ctx) 179300f19dcSKumar Kartikeya Dwivedi { 180300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 181300f19dcSKumar Kartikeya Dwivedi return 0; 182300f19dcSKumar Kartikeya Dwivedi } 183300f19dcSKumar Kartikeya Dwivedi 184300f19dcSKumar Kartikeya Dwivedi SEC("?tracepoint/xyz") 185300f19dcSKumar Kartikeya Dwivedi int map_compat_tp(void *ctx) 186300f19dcSKumar Kartikeya Dwivedi { 187300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 188300f19dcSKumar Kartikeya Dwivedi return 0; 189300f19dcSKumar Kartikeya Dwivedi } 190300f19dcSKumar Kartikeya Dwivedi 191300f19dcSKumar Kartikeya Dwivedi SEC("?perf_event") 192300f19dcSKumar Kartikeya Dwivedi int map_compat_perf(void *ctx) 193300f19dcSKumar Kartikeya Dwivedi { 194300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 195300f19dcSKumar Kartikeya Dwivedi return 0; 196300f19dcSKumar Kartikeya Dwivedi } 197300f19dcSKumar Kartikeya Dwivedi 198300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp/xyz") 199300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp(void *ctx) 200300f19dcSKumar Kartikeya Dwivedi { 201300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 202300f19dcSKumar Kartikeya Dwivedi return 0; 203300f19dcSKumar Kartikeya Dwivedi } 204300f19dcSKumar Kartikeya Dwivedi 205300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp.w/xyz") 206300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp_w(void *ctx) 207300f19dcSKumar Kartikeya Dwivedi { 208300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 209300f19dcSKumar Kartikeya Dwivedi return 0; 210300f19dcSKumar Kartikeya Dwivedi } 211300f19dcSKumar Kartikeya Dwivedi 212300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 213300f19dcSKumar Kartikeya Dwivedi int obj_type_id_oor(void *ctx) 214300f19dcSKumar Kartikeya Dwivedi { 215300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(~0UL, NULL); 216300f19dcSKumar Kartikeya Dwivedi return 0; 217300f19dcSKumar Kartikeya Dwivedi } 218300f19dcSKumar Kartikeya Dwivedi 219300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 220300f19dcSKumar Kartikeya Dwivedi int obj_new_no_composite(void *ctx) 221300f19dcSKumar Kartikeya Dwivedi { 222300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(bpf_core_type_id_local(int), (void *)42); 223300f19dcSKumar Kartikeya Dwivedi return 0; 224300f19dcSKumar Kartikeya Dwivedi } 225300f19dcSKumar Kartikeya Dwivedi 226300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 227300f19dcSKumar Kartikeya Dwivedi int obj_new_no_struct(void *ctx) 228300f19dcSKumar Kartikeya Dwivedi { 229300f19dcSKumar Kartikeya Dwivedi 230300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(union { int data; unsigned udata; }); 231300f19dcSKumar Kartikeya Dwivedi return 0; 232300f19dcSKumar Kartikeya Dwivedi } 233300f19dcSKumar Kartikeya Dwivedi 234300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 235300f19dcSKumar Kartikeya Dwivedi int obj_drop_non_zero_off(void *ctx) 236300f19dcSKumar Kartikeya Dwivedi { 237300f19dcSKumar Kartikeya Dwivedi void *f; 238300f19dcSKumar Kartikeya Dwivedi 239300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(struct foo); 240300f19dcSKumar Kartikeya Dwivedi if (!f) 241300f19dcSKumar Kartikeya Dwivedi return 0; 242300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f+1); 243300f19dcSKumar Kartikeya Dwivedi return 0; 244300f19dcSKumar Kartikeya Dwivedi } 245300f19dcSKumar Kartikeya Dwivedi 246300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 247300f19dcSKumar Kartikeya Dwivedi int new_null_ret(void *ctx) 248300f19dcSKumar Kartikeya Dwivedi { 249300f19dcSKumar Kartikeya Dwivedi return bpf_obj_new(struct foo)->data; 250300f19dcSKumar Kartikeya Dwivedi } 251300f19dcSKumar Kartikeya Dwivedi 252300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 253300f19dcSKumar Kartikeya Dwivedi int obj_new_acq(void *ctx) 254300f19dcSKumar Kartikeya Dwivedi { 255300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(struct foo); 256300f19dcSKumar Kartikeya Dwivedi return 0; 257300f19dcSKumar Kartikeya Dwivedi } 258300f19dcSKumar Kartikeya Dwivedi 259300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 260300f19dcSKumar Kartikeya Dwivedi int use_after_drop(void *ctx) 261300f19dcSKumar Kartikeya Dwivedi { 262300f19dcSKumar Kartikeya Dwivedi struct foo *f; 263300f19dcSKumar Kartikeya Dwivedi 264300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 265300f19dcSKumar Kartikeya Dwivedi if (!f) 266300f19dcSKumar Kartikeya Dwivedi return 0; 267300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 268300f19dcSKumar Kartikeya Dwivedi return f->data; 269300f19dcSKumar Kartikeya Dwivedi } 270300f19dcSKumar Kartikeya Dwivedi 271300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 272300f19dcSKumar Kartikeya Dwivedi int ptr_walk_scalar(void *ctx) 273300f19dcSKumar Kartikeya Dwivedi { 274300f19dcSKumar Kartikeya Dwivedi struct test1 { 275300f19dcSKumar Kartikeya Dwivedi struct test2 { 276300f19dcSKumar Kartikeya Dwivedi struct test2 *next; 277300f19dcSKumar Kartikeya Dwivedi } *ptr; 278300f19dcSKumar Kartikeya Dwivedi } *p; 279300f19dcSKumar Kartikeya Dwivedi 280300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 281300f19dcSKumar Kartikeya Dwivedi if (!p) 282300f19dcSKumar Kartikeya Dwivedi return 0; 283300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(p->ptr); 284300f19dcSKumar Kartikeya Dwivedi return 0; 285300f19dcSKumar Kartikeya Dwivedi } 286300f19dcSKumar Kartikeya Dwivedi 287300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 288300f19dcSKumar Kartikeya Dwivedi int direct_read_lock(void *ctx) 289300f19dcSKumar Kartikeya Dwivedi { 290300f19dcSKumar Kartikeya Dwivedi struct foo *f; 291300f19dcSKumar Kartikeya Dwivedi 292300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 293300f19dcSKumar Kartikeya Dwivedi if (!f) 294300f19dcSKumar Kartikeya Dwivedi return 0; 295300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->lock; 296300f19dcSKumar Kartikeya Dwivedi } 297300f19dcSKumar Kartikeya Dwivedi 298300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 299300f19dcSKumar Kartikeya Dwivedi int direct_write_lock(void *ctx) 300300f19dcSKumar Kartikeya Dwivedi { 301300f19dcSKumar Kartikeya Dwivedi struct foo *f; 302300f19dcSKumar Kartikeya Dwivedi 303300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 304300f19dcSKumar Kartikeya Dwivedi if (!f) 305300f19dcSKumar Kartikeya Dwivedi return 0; 306300f19dcSKumar Kartikeya Dwivedi *(int *)&f->lock = 0; 307300f19dcSKumar Kartikeya Dwivedi return 0; 308300f19dcSKumar Kartikeya Dwivedi } 309300f19dcSKumar Kartikeya Dwivedi 310300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 311300f19dcSKumar Kartikeya Dwivedi int direct_read_head(void *ctx) 312300f19dcSKumar Kartikeya Dwivedi { 313300f19dcSKumar Kartikeya Dwivedi struct foo *f; 314300f19dcSKumar Kartikeya Dwivedi 315300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 316300f19dcSKumar Kartikeya Dwivedi if (!f) 317300f19dcSKumar Kartikeya Dwivedi return 0; 318300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->head; 319300f19dcSKumar Kartikeya Dwivedi } 320300f19dcSKumar Kartikeya Dwivedi 321300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 322300f19dcSKumar Kartikeya Dwivedi int direct_write_head(void *ctx) 323300f19dcSKumar Kartikeya Dwivedi { 324300f19dcSKumar Kartikeya Dwivedi struct foo *f; 325300f19dcSKumar Kartikeya Dwivedi 326300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 327300f19dcSKumar Kartikeya Dwivedi if (!f) 328300f19dcSKumar Kartikeya Dwivedi return 0; 329300f19dcSKumar Kartikeya Dwivedi *(int *)&f->head = 0; 330300f19dcSKumar Kartikeya Dwivedi return 0; 331300f19dcSKumar Kartikeya Dwivedi } 332300f19dcSKumar Kartikeya Dwivedi 333300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 334300f19dcSKumar Kartikeya Dwivedi int direct_read_node(void *ctx) 335300f19dcSKumar Kartikeya Dwivedi { 336300f19dcSKumar Kartikeya Dwivedi struct foo *f; 337300f19dcSKumar Kartikeya Dwivedi 338300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 339300f19dcSKumar Kartikeya Dwivedi if (!f) 340300f19dcSKumar Kartikeya Dwivedi return 0; 341*de67ba39SDave Marchevsky return *(int *)&f->node2; 342300f19dcSKumar Kartikeya Dwivedi } 343300f19dcSKumar Kartikeya Dwivedi 344300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 345300f19dcSKumar Kartikeya Dwivedi int direct_write_node(void *ctx) 346300f19dcSKumar Kartikeya Dwivedi { 347300f19dcSKumar Kartikeya Dwivedi struct foo *f; 348300f19dcSKumar Kartikeya Dwivedi 349300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 350300f19dcSKumar Kartikeya Dwivedi if (!f) 351300f19dcSKumar Kartikeya Dwivedi return 0; 352*de67ba39SDave Marchevsky *(int *)&f->node2 = 0; 353300f19dcSKumar Kartikeya Dwivedi return 0; 354300f19dcSKumar Kartikeya Dwivedi } 355300f19dcSKumar Kartikeya Dwivedi 356300f19dcSKumar Kartikeya Dwivedi static __always_inline 357*de67ba39SDave Marchevsky int use_after_unlock(bool push_front) 358300f19dcSKumar Kartikeya Dwivedi { 359300f19dcSKumar Kartikeya Dwivedi struct foo *f; 360300f19dcSKumar Kartikeya Dwivedi 361300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 362300f19dcSKumar Kartikeya Dwivedi if (!f) 363300f19dcSKumar Kartikeya Dwivedi return 0; 364300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 365300f19dcSKumar Kartikeya Dwivedi f->data = 42; 366*de67ba39SDave Marchevsky if (push_front) 367*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2); 368*de67ba39SDave Marchevsky else 369*de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2); 370300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 371300f19dcSKumar Kartikeya Dwivedi 372300f19dcSKumar Kartikeya Dwivedi return f->data; 373300f19dcSKumar Kartikeya Dwivedi } 374300f19dcSKumar Kartikeya Dwivedi 375300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 376300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_front(void *ctx) 377300f19dcSKumar Kartikeya Dwivedi { 378*de67ba39SDave Marchevsky return use_after_unlock(true); 379300f19dcSKumar Kartikeya Dwivedi } 380300f19dcSKumar Kartikeya Dwivedi 381300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 382300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_back(void *ctx) 383300f19dcSKumar Kartikeya Dwivedi { 384*de67ba39SDave Marchevsky return use_after_unlock(false); 385300f19dcSKumar Kartikeya Dwivedi } 386300f19dcSKumar Kartikeya Dwivedi 387300f19dcSKumar Kartikeya Dwivedi static __always_inline 388*de67ba39SDave Marchevsky int list_double_add(bool push_front) 389300f19dcSKumar Kartikeya Dwivedi { 390300f19dcSKumar Kartikeya Dwivedi struct foo *f; 391300f19dcSKumar Kartikeya Dwivedi 392300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 393300f19dcSKumar Kartikeya Dwivedi if (!f) 394300f19dcSKumar Kartikeya Dwivedi return 0; 395300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 396*de67ba39SDave Marchevsky if (push_front) { 397*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2); 398*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2); 399*de67ba39SDave Marchevsky } else { 400*de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2); 401*de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2); 402*de67ba39SDave Marchevsky } 403300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 404300f19dcSKumar Kartikeya Dwivedi 405300f19dcSKumar Kartikeya Dwivedi return 0; 406300f19dcSKumar Kartikeya Dwivedi } 407300f19dcSKumar Kartikeya Dwivedi 408300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 409300f19dcSKumar Kartikeya Dwivedi int double_push_front(void *ctx) 410300f19dcSKumar Kartikeya Dwivedi { 411*de67ba39SDave Marchevsky return list_double_add(true); 412300f19dcSKumar Kartikeya Dwivedi } 413300f19dcSKumar Kartikeya Dwivedi 414300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 415300f19dcSKumar Kartikeya Dwivedi int double_push_back(void *ctx) 416300f19dcSKumar Kartikeya Dwivedi { 417*de67ba39SDave Marchevsky return list_double_add(false); 418300f19dcSKumar Kartikeya Dwivedi } 419300f19dcSKumar Kartikeya Dwivedi 420300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 421300f19dcSKumar Kartikeya Dwivedi int no_node_value_type(void *ctx) 422300f19dcSKumar Kartikeya Dwivedi { 423300f19dcSKumar Kartikeya Dwivedi void *p; 424300f19dcSKumar Kartikeya Dwivedi 425300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(struct { int data; }); 426300f19dcSKumar Kartikeya Dwivedi if (!p) 427300f19dcSKumar Kartikeya Dwivedi return 0; 428300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 429300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, p); 430300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 431300f19dcSKumar Kartikeya Dwivedi 432300f19dcSKumar Kartikeya Dwivedi return 0; 433300f19dcSKumar Kartikeya Dwivedi } 434300f19dcSKumar Kartikeya Dwivedi 435300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 436300f19dcSKumar Kartikeya Dwivedi int incorrect_value_type(void *ctx) 437300f19dcSKumar Kartikeya Dwivedi { 438300f19dcSKumar Kartikeya Dwivedi struct bar *b; 439300f19dcSKumar Kartikeya Dwivedi 440300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 441300f19dcSKumar Kartikeya Dwivedi if (!b) 442300f19dcSKumar Kartikeya Dwivedi return 0; 443300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 444300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &b->node); 445300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 446300f19dcSKumar Kartikeya Dwivedi 447300f19dcSKumar Kartikeya Dwivedi return 0; 448300f19dcSKumar Kartikeya Dwivedi } 449300f19dcSKumar Kartikeya Dwivedi 450300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 451300f19dcSKumar Kartikeya Dwivedi int incorrect_node_var_off(struct __sk_buff *ctx) 452300f19dcSKumar Kartikeya Dwivedi { 453300f19dcSKumar Kartikeya Dwivedi struct foo *f; 454300f19dcSKumar Kartikeya Dwivedi 455300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 456300f19dcSKumar Kartikeya Dwivedi if (!f) 457300f19dcSKumar Kartikeya Dwivedi return 0; 458300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 459*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, (void *)&f->node2 + ctx->protocol); 460300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 461300f19dcSKumar Kartikeya Dwivedi 462300f19dcSKumar Kartikeya Dwivedi return 0; 463300f19dcSKumar Kartikeya Dwivedi } 464300f19dcSKumar Kartikeya Dwivedi 465300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 466300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off1(void *ctx) 467300f19dcSKumar Kartikeya Dwivedi { 468300f19dcSKumar Kartikeya Dwivedi struct foo *f; 469300f19dcSKumar Kartikeya Dwivedi 470300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 471300f19dcSKumar Kartikeya Dwivedi if (!f) 472300f19dcSKumar Kartikeya Dwivedi return 0; 473300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 474*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, (void *)&f->node2 + 1); 475300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 476300f19dcSKumar Kartikeya Dwivedi 477300f19dcSKumar Kartikeya Dwivedi return 0; 478300f19dcSKumar Kartikeya Dwivedi } 479300f19dcSKumar Kartikeya Dwivedi 480300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 481300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off2(void *ctx) 482300f19dcSKumar Kartikeya Dwivedi { 483300f19dcSKumar Kartikeya Dwivedi struct foo *f; 484300f19dcSKumar Kartikeya Dwivedi 485300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 486300f19dcSKumar Kartikeya Dwivedi if (!f) 487300f19dcSKumar Kartikeya Dwivedi return 0; 488300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 489*de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node); 490300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 491300f19dcSKumar Kartikeya Dwivedi 492300f19dcSKumar Kartikeya Dwivedi return 0; 493300f19dcSKumar Kartikeya Dwivedi } 494300f19dcSKumar Kartikeya Dwivedi 495300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 496300f19dcSKumar Kartikeya Dwivedi int no_head_type(void *ctx) 497300f19dcSKumar Kartikeya Dwivedi { 498300f19dcSKumar Kartikeya Dwivedi void *p; 499300f19dcSKumar Kartikeya Dwivedi 500300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(struct { int data; })); 501300f19dcSKumar Kartikeya Dwivedi if (!p) 502300f19dcSKumar Kartikeya Dwivedi return 0; 503300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 504300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(p, NULL); 505300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 506300f19dcSKumar Kartikeya Dwivedi 507300f19dcSKumar Kartikeya Dwivedi return 0; 508300f19dcSKumar Kartikeya Dwivedi } 509300f19dcSKumar Kartikeya Dwivedi 510300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 511300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off1(struct __sk_buff *ctx) 512300f19dcSKumar Kartikeya Dwivedi { 513300f19dcSKumar Kartikeya Dwivedi struct foo *f; 514300f19dcSKumar Kartikeya Dwivedi 515300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 516300f19dcSKumar Kartikeya Dwivedi if (!f) 517300f19dcSKumar Kartikeya Dwivedi return 0; 518300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 519*de67ba39SDave Marchevsky bpf_list_push_front((void *)&ghead + ctx->protocol, &f->node2); 520300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 521300f19dcSKumar Kartikeya Dwivedi 522300f19dcSKumar Kartikeya Dwivedi return 0; 523300f19dcSKumar Kartikeya Dwivedi } 524300f19dcSKumar Kartikeya Dwivedi 525300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 526300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off2(struct __sk_buff *ctx) 527300f19dcSKumar Kartikeya Dwivedi { 528300f19dcSKumar Kartikeya Dwivedi struct foo *f; 529300f19dcSKumar Kartikeya Dwivedi 530300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 531300f19dcSKumar Kartikeya Dwivedi if (!f) 532300f19dcSKumar Kartikeya Dwivedi return 0; 533300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 534*de67ba39SDave Marchevsky bpf_list_push_front((void *)&f->head + ctx->protocol, &f->node2); 535300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 536300f19dcSKumar Kartikeya Dwivedi 537300f19dcSKumar Kartikeya Dwivedi return 0; 538300f19dcSKumar Kartikeya Dwivedi } 539300f19dcSKumar Kartikeya Dwivedi 540300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 541300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off1(void *ctx) 542300f19dcSKumar Kartikeya Dwivedi { 543300f19dcSKumar Kartikeya Dwivedi struct foo *f; 544300f19dcSKumar Kartikeya Dwivedi struct bar *b; 545300f19dcSKumar Kartikeya Dwivedi 546300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 547300f19dcSKumar Kartikeya Dwivedi if (!f) 548300f19dcSKumar Kartikeya Dwivedi return 0; 549300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 550300f19dcSKumar Kartikeya Dwivedi if (!b) { 551300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 552300f19dcSKumar Kartikeya Dwivedi return 0; 553300f19dcSKumar Kartikeya Dwivedi } 554300f19dcSKumar Kartikeya Dwivedi 555300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&f->lock); 556300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + 1, &b->node); 557300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&f->lock); 558300f19dcSKumar Kartikeya Dwivedi 559300f19dcSKumar Kartikeya Dwivedi return 0; 560300f19dcSKumar Kartikeya Dwivedi } 561300f19dcSKumar Kartikeya Dwivedi 562300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 563300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off2(void *ctx) 564300f19dcSKumar Kartikeya Dwivedi { 565300f19dcSKumar Kartikeya Dwivedi struct foo *f; 566300f19dcSKumar Kartikeya Dwivedi 567300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 568300f19dcSKumar Kartikeya Dwivedi if (!f) 569300f19dcSKumar Kartikeya Dwivedi return 0; 570300f19dcSKumar Kartikeya Dwivedi 571300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 572*de67ba39SDave Marchevsky bpf_list_push_front((void *)&ghead + 1, &f->node2); 573300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 574300f19dcSKumar Kartikeya Dwivedi 575300f19dcSKumar Kartikeya Dwivedi return 0; 576300f19dcSKumar Kartikeya Dwivedi } 577300f19dcSKumar Kartikeya Dwivedi 578300f19dcSKumar Kartikeya Dwivedi static __always_inline 579300f19dcSKumar Kartikeya Dwivedi int pop_ptr_off(void *(*op)(void *head)) 580300f19dcSKumar Kartikeya Dwivedi { 581300f19dcSKumar Kartikeya Dwivedi struct { 582300f19dcSKumar Kartikeya Dwivedi struct bpf_list_head head __contains(foo, node2); 583300f19dcSKumar Kartikeya Dwivedi struct bpf_spin_lock lock; 584300f19dcSKumar Kartikeya Dwivedi } *p; 585300f19dcSKumar Kartikeya Dwivedi struct bpf_list_node *n; 586300f19dcSKumar Kartikeya Dwivedi 587300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 588300f19dcSKumar Kartikeya Dwivedi if (!p) 589300f19dcSKumar Kartikeya Dwivedi return 0; 590300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&p->lock); 591300f19dcSKumar Kartikeya Dwivedi n = op(&p->head); 592300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&p->lock); 593300f19dcSKumar Kartikeya Dwivedi 594300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(n); 595300f19dcSKumar Kartikeya Dwivedi return 0; 596300f19dcSKumar Kartikeya Dwivedi } 597300f19dcSKumar Kartikeya Dwivedi 598300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 599300f19dcSKumar Kartikeya Dwivedi int pop_front_off(void *ctx) 600300f19dcSKumar Kartikeya Dwivedi { 601300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_front); 602300f19dcSKumar Kartikeya Dwivedi } 603300f19dcSKumar Kartikeya Dwivedi 604300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 605300f19dcSKumar Kartikeya Dwivedi int pop_back_off(void *ctx) 606300f19dcSKumar Kartikeya Dwivedi { 607300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_back); 608300f19dcSKumar Kartikeya Dwivedi } 609300f19dcSKumar Kartikeya Dwivedi 610300f19dcSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL"; 611