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, push_front, &f->head); 58300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, push_back, &f->head); 59300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_front, &f->head); 60300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_back, &f->head); 61300f19dcSKumar Kartikeya Dwivedi 62300f19dcSKumar Kartikeya Dwivedi CHECK(global, push_front, &ghead); 63300f19dcSKumar Kartikeya Dwivedi CHECK(global, push_back, &ghead); 64300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_front, &ghead); 65300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_back, &ghead); 66300f19dcSKumar Kartikeya Dwivedi 67300f19dcSKumar Kartikeya Dwivedi CHECK(map, push_front, &v->head); 68300f19dcSKumar Kartikeya Dwivedi CHECK(map, push_back, &v->head); 69300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_front, &v->head); 70300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_back, &v->head); 71300f19dcSKumar Kartikeya Dwivedi 72300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, push_front, &iv->head); 73300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, push_back, &iv->head); 74300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_front, &iv->head); 75300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_back, &iv->head); 76300f19dcSKumar Kartikeya Dwivedi 77300f19dcSKumar Kartikeya Dwivedi #undef CHECK 78300f19dcSKumar Kartikeya Dwivedi 79300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, lexpr, hexpr) \ 80300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \ 81300f19dcSKumar Kartikeya Dwivedi int test##_incorrect_lock_##op(void *ctx) \ 82300f19dcSKumar Kartikeya Dwivedi { \ 83300f19dcSKumar Kartikeya Dwivedi INIT; \ 84300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \ 85300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(lexpr); \ 86300f19dcSKumar Kartikeya Dwivedi p(hexpr); \ 87300f19dcSKumar Kartikeya Dwivedi return 0; \ 88300f19dcSKumar Kartikeya Dwivedi } 89300f19dcSKumar Kartikeya Dwivedi 90300f19dcSKumar Kartikeya Dwivedi #define CHECK_OP(op) \ 91300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_kptr, op, &f1->lock, &f2->head); \ 92*0b2971a2SAlexei Starovoitov CHECK(kptr_global, op, &f1->lock, &ghead); \ 93300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_map, op, &f1->lock, &v->head); \ 94300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_inner_map, op, &f1->lock, &iv->head); \ 95300f19dcSKumar Kartikeya Dwivedi \ 96*0b2971a2SAlexei Starovoitov CHECK(global_global, op, &glock2, &ghead); \ 97*0b2971a2SAlexei Starovoitov CHECK(global_kptr, op, &glock, &f1->head); \ 98*0b2971a2SAlexei Starovoitov CHECK(global_map, op, &glock, &v->head); \ 99*0b2971a2SAlexei Starovoitov CHECK(global_inner_map, op, &glock, &iv->head); \ 100*0b2971a2SAlexei Starovoitov \ 101300f19dcSKumar Kartikeya Dwivedi CHECK(map_map, op, &v->lock, &v2->head); \ 102300f19dcSKumar Kartikeya Dwivedi CHECK(map_kptr, op, &v->lock, &f2->head); \ 103*0b2971a2SAlexei Starovoitov CHECK(map_global, op, &v->lock, &ghead); \ 104300f19dcSKumar Kartikeya Dwivedi CHECK(map_inner_map, op, &v->lock, &iv->head); \ 105300f19dcSKumar Kartikeya Dwivedi \ 106300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head); \ 107300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_kptr, op, &iv->lock, &f2->head); \ 108*0b2971a2SAlexei Starovoitov CHECK(inner_map_global, op, &iv->lock, &ghead); \ 109300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_map, op, &iv->lock, &v->head); 110300f19dcSKumar Kartikeya Dwivedi 111300f19dcSKumar Kartikeya Dwivedi CHECK_OP(push_front); 112300f19dcSKumar Kartikeya Dwivedi CHECK_OP(push_back); 113300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_front); 114300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_back); 115300f19dcSKumar Kartikeya Dwivedi 116300f19dcSKumar Kartikeya Dwivedi #undef CHECK 117300f19dcSKumar Kartikeya Dwivedi #undef CHECK_OP 118300f19dcSKumar Kartikeya Dwivedi #undef INIT 119300f19dcSKumar Kartikeya Dwivedi 120300f19dcSKumar Kartikeya Dwivedi SEC("?kprobe/xyz") 121300f19dcSKumar Kartikeya Dwivedi int map_compat_kprobe(void *ctx) 122300f19dcSKumar Kartikeya Dwivedi { 123300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 124300f19dcSKumar Kartikeya Dwivedi return 0; 125300f19dcSKumar Kartikeya Dwivedi } 126300f19dcSKumar Kartikeya Dwivedi 127300f19dcSKumar Kartikeya Dwivedi SEC("?kretprobe/xyz") 128300f19dcSKumar Kartikeya Dwivedi int map_compat_kretprobe(void *ctx) 129300f19dcSKumar Kartikeya Dwivedi { 130300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 131300f19dcSKumar Kartikeya Dwivedi return 0; 132300f19dcSKumar Kartikeya Dwivedi } 133300f19dcSKumar Kartikeya Dwivedi 134300f19dcSKumar Kartikeya Dwivedi SEC("?tracepoint/xyz") 135300f19dcSKumar Kartikeya Dwivedi int map_compat_tp(void *ctx) 136300f19dcSKumar Kartikeya Dwivedi { 137300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 138300f19dcSKumar Kartikeya Dwivedi return 0; 139300f19dcSKumar Kartikeya Dwivedi } 140300f19dcSKumar Kartikeya Dwivedi 141300f19dcSKumar Kartikeya Dwivedi SEC("?perf_event") 142300f19dcSKumar Kartikeya Dwivedi int map_compat_perf(void *ctx) 143300f19dcSKumar Kartikeya Dwivedi { 144300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 145300f19dcSKumar Kartikeya Dwivedi return 0; 146300f19dcSKumar Kartikeya Dwivedi } 147300f19dcSKumar Kartikeya Dwivedi 148300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp/xyz") 149300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp(void *ctx) 150300f19dcSKumar Kartikeya Dwivedi { 151300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 152300f19dcSKumar Kartikeya Dwivedi return 0; 153300f19dcSKumar Kartikeya Dwivedi } 154300f19dcSKumar Kartikeya Dwivedi 155300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp.w/xyz") 156300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp_w(void *ctx) 157300f19dcSKumar Kartikeya Dwivedi { 158300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL); 159300f19dcSKumar Kartikeya Dwivedi return 0; 160300f19dcSKumar Kartikeya Dwivedi } 161300f19dcSKumar Kartikeya Dwivedi 162300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 163300f19dcSKumar Kartikeya Dwivedi int obj_type_id_oor(void *ctx) 164300f19dcSKumar Kartikeya Dwivedi { 165300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(~0UL, NULL); 166300f19dcSKumar Kartikeya Dwivedi return 0; 167300f19dcSKumar Kartikeya Dwivedi } 168300f19dcSKumar Kartikeya Dwivedi 169300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 170300f19dcSKumar Kartikeya Dwivedi int obj_new_no_composite(void *ctx) 171300f19dcSKumar Kartikeya Dwivedi { 172300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(bpf_core_type_id_local(int), (void *)42); 173300f19dcSKumar Kartikeya Dwivedi return 0; 174300f19dcSKumar Kartikeya Dwivedi } 175300f19dcSKumar Kartikeya Dwivedi 176300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 177300f19dcSKumar Kartikeya Dwivedi int obj_new_no_struct(void *ctx) 178300f19dcSKumar Kartikeya Dwivedi { 179300f19dcSKumar Kartikeya Dwivedi 180300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(union { int data; unsigned udata; }); 181300f19dcSKumar Kartikeya Dwivedi return 0; 182300f19dcSKumar Kartikeya Dwivedi } 183300f19dcSKumar Kartikeya Dwivedi 184300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 185300f19dcSKumar Kartikeya Dwivedi int obj_drop_non_zero_off(void *ctx) 186300f19dcSKumar Kartikeya Dwivedi { 187300f19dcSKumar Kartikeya Dwivedi void *f; 188300f19dcSKumar Kartikeya Dwivedi 189300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(struct foo); 190300f19dcSKumar Kartikeya Dwivedi if (!f) 191300f19dcSKumar Kartikeya Dwivedi return 0; 192300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f+1); 193300f19dcSKumar Kartikeya Dwivedi return 0; 194300f19dcSKumar Kartikeya Dwivedi } 195300f19dcSKumar Kartikeya Dwivedi 196300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 197300f19dcSKumar Kartikeya Dwivedi int new_null_ret(void *ctx) 198300f19dcSKumar Kartikeya Dwivedi { 199300f19dcSKumar Kartikeya Dwivedi return bpf_obj_new(struct foo)->data; 200300f19dcSKumar Kartikeya Dwivedi } 201300f19dcSKumar Kartikeya Dwivedi 202300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 203300f19dcSKumar Kartikeya Dwivedi int obj_new_acq(void *ctx) 204300f19dcSKumar Kartikeya Dwivedi { 205300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(struct foo); 206300f19dcSKumar Kartikeya Dwivedi return 0; 207300f19dcSKumar Kartikeya Dwivedi } 208300f19dcSKumar Kartikeya Dwivedi 209300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 210300f19dcSKumar Kartikeya Dwivedi int use_after_drop(void *ctx) 211300f19dcSKumar Kartikeya Dwivedi { 212300f19dcSKumar Kartikeya Dwivedi struct foo *f; 213300f19dcSKumar Kartikeya Dwivedi 214300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 215300f19dcSKumar Kartikeya Dwivedi if (!f) 216300f19dcSKumar Kartikeya Dwivedi return 0; 217300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 218300f19dcSKumar Kartikeya Dwivedi return f->data; 219300f19dcSKumar Kartikeya Dwivedi } 220300f19dcSKumar Kartikeya Dwivedi 221300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 222300f19dcSKumar Kartikeya Dwivedi int ptr_walk_scalar(void *ctx) 223300f19dcSKumar Kartikeya Dwivedi { 224300f19dcSKumar Kartikeya Dwivedi struct test1 { 225300f19dcSKumar Kartikeya Dwivedi struct test2 { 226300f19dcSKumar Kartikeya Dwivedi struct test2 *next; 227300f19dcSKumar Kartikeya Dwivedi } *ptr; 228300f19dcSKumar Kartikeya Dwivedi } *p; 229300f19dcSKumar Kartikeya Dwivedi 230300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 231300f19dcSKumar Kartikeya Dwivedi if (!p) 232300f19dcSKumar Kartikeya Dwivedi return 0; 233300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(p->ptr); 234300f19dcSKumar Kartikeya Dwivedi return 0; 235300f19dcSKumar Kartikeya Dwivedi } 236300f19dcSKumar Kartikeya Dwivedi 237300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 238300f19dcSKumar Kartikeya Dwivedi int direct_read_lock(void *ctx) 239300f19dcSKumar Kartikeya Dwivedi { 240300f19dcSKumar Kartikeya Dwivedi struct foo *f; 241300f19dcSKumar Kartikeya Dwivedi 242300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 243300f19dcSKumar Kartikeya Dwivedi if (!f) 244300f19dcSKumar Kartikeya Dwivedi return 0; 245300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->lock; 246300f19dcSKumar Kartikeya Dwivedi } 247300f19dcSKumar Kartikeya Dwivedi 248300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 249300f19dcSKumar Kartikeya Dwivedi int direct_write_lock(void *ctx) 250300f19dcSKumar Kartikeya Dwivedi { 251300f19dcSKumar Kartikeya Dwivedi struct foo *f; 252300f19dcSKumar Kartikeya Dwivedi 253300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 254300f19dcSKumar Kartikeya Dwivedi if (!f) 255300f19dcSKumar Kartikeya Dwivedi return 0; 256300f19dcSKumar Kartikeya Dwivedi *(int *)&f->lock = 0; 257300f19dcSKumar Kartikeya Dwivedi return 0; 258300f19dcSKumar Kartikeya Dwivedi } 259300f19dcSKumar Kartikeya Dwivedi 260300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 261300f19dcSKumar Kartikeya Dwivedi int direct_read_head(void *ctx) 262300f19dcSKumar Kartikeya Dwivedi { 263300f19dcSKumar Kartikeya Dwivedi struct foo *f; 264300f19dcSKumar Kartikeya Dwivedi 265300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 266300f19dcSKumar Kartikeya Dwivedi if (!f) 267300f19dcSKumar Kartikeya Dwivedi return 0; 268300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->head; 269300f19dcSKumar Kartikeya Dwivedi } 270300f19dcSKumar Kartikeya Dwivedi 271300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 272300f19dcSKumar Kartikeya Dwivedi int direct_write_head(void *ctx) 273300f19dcSKumar Kartikeya Dwivedi { 274300f19dcSKumar Kartikeya Dwivedi struct foo *f; 275300f19dcSKumar Kartikeya Dwivedi 276300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 277300f19dcSKumar Kartikeya Dwivedi if (!f) 278300f19dcSKumar Kartikeya Dwivedi return 0; 279300f19dcSKumar Kartikeya Dwivedi *(int *)&f->head = 0; 280300f19dcSKumar Kartikeya Dwivedi return 0; 281300f19dcSKumar Kartikeya Dwivedi } 282300f19dcSKumar Kartikeya Dwivedi 283300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 284300f19dcSKumar Kartikeya Dwivedi int direct_read_node(void *ctx) 285300f19dcSKumar Kartikeya Dwivedi { 286300f19dcSKumar Kartikeya Dwivedi struct foo *f; 287300f19dcSKumar Kartikeya Dwivedi 288300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 289300f19dcSKumar Kartikeya Dwivedi if (!f) 290300f19dcSKumar Kartikeya Dwivedi return 0; 291300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->node; 292300f19dcSKumar Kartikeya Dwivedi } 293300f19dcSKumar Kartikeya Dwivedi 294300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 295300f19dcSKumar Kartikeya Dwivedi int direct_write_node(void *ctx) 296300f19dcSKumar Kartikeya Dwivedi { 297300f19dcSKumar Kartikeya Dwivedi struct foo *f; 298300f19dcSKumar Kartikeya Dwivedi 299300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 300300f19dcSKumar Kartikeya Dwivedi if (!f) 301300f19dcSKumar Kartikeya Dwivedi return 0; 302300f19dcSKumar Kartikeya Dwivedi *(int *)&f->node = 0; 303300f19dcSKumar Kartikeya Dwivedi return 0; 304300f19dcSKumar Kartikeya Dwivedi } 305300f19dcSKumar Kartikeya Dwivedi 306300f19dcSKumar Kartikeya Dwivedi static __always_inline 307300f19dcSKumar Kartikeya Dwivedi int write_after_op(void (*push_op)(void *head, void *node)) 308300f19dcSKumar Kartikeya Dwivedi { 309300f19dcSKumar Kartikeya Dwivedi struct foo *f; 310300f19dcSKumar Kartikeya Dwivedi 311300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 312300f19dcSKumar Kartikeya Dwivedi if (!f) 313300f19dcSKumar Kartikeya Dwivedi return 0; 314300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 315300f19dcSKumar Kartikeya Dwivedi push_op(&ghead, &f->node); 316300f19dcSKumar Kartikeya Dwivedi f->data = 42; 317300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 318300f19dcSKumar Kartikeya Dwivedi 319300f19dcSKumar Kartikeya Dwivedi return 0; 320300f19dcSKumar Kartikeya Dwivedi } 321300f19dcSKumar Kartikeya Dwivedi 322300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 323300f19dcSKumar Kartikeya Dwivedi int write_after_push_front(void *ctx) 324300f19dcSKumar Kartikeya Dwivedi { 325300f19dcSKumar Kartikeya Dwivedi return write_after_op((void *)bpf_list_push_front); 326300f19dcSKumar Kartikeya Dwivedi } 327300f19dcSKumar Kartikeya Dwivedi 328300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 329300f19dcSKumar Kartikeya Dwivedi int write_after_push_back(void *ctx) 330300f19dcSKumar Kartikeya Dwivedi { 331300f19dcSKumar Kartikeya Dwivedi return write_after_op((void *)bpf_list_push_back); 332300f19dcSKumar Kartikeya Dwivedi } 333300f19dcSKumar Kartikeya Dwivedi 334300f19dcSKumar Kartikeya Dwivedi static __always_inline 335300f19dcSKumar Kartikeya Dwivedi int use_after_unlock(void (*op)(void *head, void *node)) 336300f19dcSKumar Kartikeya Dwivedi { 337300f19dcSKumar Kartikeya Dwivedi struct foo *f; 338300f19dcSKumar Kartikeya Dwivedi 339300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 340300f19dcSKumar Kartikeya Dwivedi if (!f) 341300f19dcSKumar Kartikeya Dwivedi return 0; 342300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 343300f19dcSKumar Kartikeya Dwivedi f->data = 42; 344300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 345300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 346300f19dcSKumar Kartikeya Dwivedi 347300f19dcSKumar Kartikeya Dwivedi return f->data; 348300f19dcSKumar Kartikeya Dwivedi } 349300f19dcSKumar Kartikeya Dwivedi 350300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 351300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_front(void *ctx) 352300f19dcSKumar Kartikeya Dwivedi { 353300f19dcSKumar Kartikeya Dwivedi return use_after_unlock((void *)bpf_list_push_front); 354300f19dcSKumar Kartikeya Dwivedi } 355300f19dcSKumar Kartikeya Dwivedi 356300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 357300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_back(void *ctx) 358300f19dcSKumar Kartikeya Dwivedi { 359300f19dcSKumar Kartikeya Dwivedi return use_after_unlock((void *)bpf_list_push_back); 360300f19dcSKumar Kartikeya Dwivedi } 361300f19dcSKumar Kartikeya Dwivedi 362300f19dcSKumar Kartikeya Dwivedi static __always_inline 363300f19dcSKumar Kartikeya Dwivedi int list_double_add(void (*op)(void *head, void *node)) 364300f19dcSKumar Kartikeya Dwivedi { 365300f19dcSKumar Kartikeya Dwivedi struct foo *f; 366300f19dcSKumar Kartikeya Dwivedi 367300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 368300f19dcSKumar Kartikeya Dwivedi if (!f) 369300f19dcSKumar Kartikeya Dwivedi return 0; 370300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 371300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 372300f19dcSKumar Kartikeya Dwivedi op(&ghead, &f->node); 373300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 374300f19dcSKumar Kartikeya Dwivedi 375300f19dcSKumar Kartikeya Dwivedi return 0; 376300f19dcSKumar Kartikeya Dwivedi } 377300f19dcSKumar Kartikeya Dwivedi 378300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 379300f19dcSKumar Kartikeya Dwivedi int double_push_front(void *ctx) 380300f19dcSKumar Kartikeya Dwivedi { 381300f19dcSKumar Kartikeya Dwivedi return list_double_add((void *)bpf_list_push_front); 382300f19dcSKumar Kartikeya Dwivedi } 383300f19dcSKumar Kartikeya Dwivedi 384300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 385300f19dcSKumar Kartikeya Dwivedi int double_push_back(void *ctx) 386300f19dcSKumar Kartikeya Dwivedi { 387300f19dcSKumar Kartikeya Dwivedi return list_double_add((void *)bpf_list_push_back); 388300f19dcSKumar Kartikeya Dwivedi } 389300f19dcSKumar Kartikeya Dwivedi 390300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 391300f19dcSKumar Kartikeya Dwivedi int no_node_value_type(void *ctx) 392300f19dcSKumar Kartikeya Dwivedi { 393300f19dcSKumar Kartikeya Dwivedi void *p; 394300f19dcSKumar Kartikeya Dwivedi 395300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(struct { int data; }); 396300f19dcSKumar Kartikeya Dwivedi if (!p) 397300f19dcSKumar Kartikeya Dwivedi return 0; 398300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 399300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, p); 400300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 401300f19dcSKumar Kartikeya Dwivedi 402300f19dcSKumar Kartikeya Dwivedi return 0; 403300f19dcSKumar Kartikeya Dwivedi } 404300f19dcSKumar Kartikeya Dwivedi 405300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 406300f19dcSKumar Kartikeya Dwivedi int incorrect_value_type(void *ctx) 407300f19dcSKumar Kartikeya Dwivedi { 408300f19dcSKumar Kartikeya Dwivedi struct bar *b; 409300f19dcSKumar Kartikeya Dwivedi 410300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 411300f19dcSKumar Kartikeya Dwivedi if (!b) 412300f19dcSKumar Kartikeya Dwivedi return 0; 413300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 414300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &b->node); 415300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 416300f19dcSKumar Kartikeya Dwivedi 417300f19dcSKumar Kartikeya Dwivedi return 0; 418300f19dcSKumar Kartikeya Dwivedi } 419300f19dcSKumar Kartikeya Dwivedi 420300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 421300f19dcSKumar Kartikeya Dwivedi int incorrect_node_var_off(struct __sk_buff *ctx) 422300f19dcSKumar Kartikeya Dwivedi { 423300f19dcSKumar Kartikeya Dwivedi struct foo *f; 424300f19dcSKumar Kartikeya Dwivedi 425300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 426300f19dcSKumar Kartikeya Dwivedi if (!f) 427300f19dcSKumar Kartikeya Dwivedi return 0; 428300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 429300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, (void *)&f->node + ctx->protocol); 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_node_off1(void *ctx) 437300f19dcSKumar Kartikeya Dwivedi { 438300f19dcSKumar Kartikeya Dwivedi struct foo *f; 439300f19dcSKumar Kartikeya Dwivedi 440300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 441300f19dcSKumar Kartikeya Dwivedi if (!f) 442300f19dcSKumar Kartikeya Dwivedi return 0; 443300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 444300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, (void *)&f->node + 1); 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_off2(void *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); 459300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &f->node2); 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 no_head_type(void *ctx) 467300f19dcSKumar Kartikeya Dwivedi { 468300f19dcSKumar Kartikeya Dwivedi void *p; 469300f19dcSKumar Kartikeya Dwivedi 470300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(struct { int data; })); 471300f19dcSKumar Kartikeya Dwivedi if (!p) 472300f19dcSKumar Kartikeya Dwivedi return 0; 473300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 474300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(p, NULL); 475300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&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_head_var_off1(struct __sk_buff *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); 489300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&ghead + ctx->protocol, &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 incorrect_head_var_off2(struct __sk_buff *ctx) 497300f19dcSKumar Kartikeya Dwivedi { 498300f19dcSKumar Kartikeya Dwivedi struct foo *f; 499300f19dcSKumar Kartikeya Dwivedi 500300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 501300f19dcSKumar Kartikeya Dwivedi if (!f) 502300f19dcSKumar Kartikeya Dwivedi return 0; 503300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 504300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + ctx->protocol, &f->node); 505300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&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_off1(void *ctx) 512300f19dcSKumar Kartikeya Dwivedi { 513300f19dcSKumar Kartikeya Dwivedi struct foo *f; 514300f19dcSKumar Kartikeya Dwivedi struct bar *b; 515300f19dcSKumar Kartikeya Dwivedi 516300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 517300f19dcSKumar Kartikeya Dwivedi if (!f) 518300f19dcSKumar Kartikeya Dwivedi return 0; 519300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); 520300f19dcSKumar Kartikeya Dwivedi if (!b) { 521300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f); 522300f19dcSKumar Kartikeya Dwivedi return 0; 523300f19dcSKumar Kartikeya Dwivedi } 524300f19dcSKumar Kartikeya Dwivedi 525300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&f->lock); 526300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + 1, &b->node); 527300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&f->lock); 528300f19dcSKumar Kartikeya Dwivedi 529300f19dcSKumar Kartikeya Dwivedi return 0; 530300f19dcSKumar Kartikeya Dwivedi } 531300f19dcSKumar Kartikeya Dwivedi 532300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 533300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off2(void *ctx) 534300f19dcSKumar Kartikeya Dwivedi { 535300f19dcSKumar Kartikeya Dwivedi struct foo *f; 536300f19dcSKumar Kartikeya Dwivedi struct bar *b; 537300f19dcSKumar Kartikeya Dwivedi 538300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); 539300f19dcSKumar Kartikeya Dwivedi if (!f) 540300f19dcSKumar Kartikeya Dwivedi return 0; 541300f19dcSKumar Kartikeya Dwivedi 542300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock); 543300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&ghead + 1, &f->node); 544300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock); 545300f19dcSKumar Kartikeya Dwivedi 546300f19dcSKumar Kartikeya Dwivedi return 0; 547300f19dcSKumar Kartikeya Dwivedi } 548300f19dcSKumar Kartikeya Dwivedi 549300f19dcSKumar Kartikeya Dwivedi static __always_inline 550300f19dcSKumar Kartikeya Dwivedi int pop_ptr_off(void *(*op)(void *head)) 551300f19dcSKumar Kartikeya Dwivedi { 552300f19dcSKumar Kartikeya Dwivedi struct { 553300f19dcSKumar Kartikeya Dwivedi struct bpf_list_head head __contains(foo, node2); 554300f19dcSKumar Kartikeya Dwivedi struct bpf_spin_lock lock; 555300f19dcSKumar Kartikeya Dwivedi } *p; 556300f19dcSKumar Kartikeya Dwivedi struct bpf_list_node *n; 557300f19dcSKumar Kartikeya Dwivedi 558300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p)); 559300f19dcSKumar Kartikeya Dwivedi if (!p) 560300f19dcSKumar Kartikeya Dwivedi return 0; 561300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&p->lock); 562300f19dcSKumar Kartikeya Dwivedi n = op(&p->head); 563300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&p->lock); 564300f19dcSKumar Kartikeya Dwivedi 565300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(n); 566300f19dcSKumar Kartikeya Dwivedi return 0; 567300f19dcSKumar Kartikeya Dwivedi } 568300f19dcSKumar Kartikeya Dwivedi 569300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 570300f19dcSKumar Kartikeya Dwivedi int pop_front_off(void *ctx) 571300f19dcSKumar Kartikeya Dwivedi { 572300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_front); 573300f19dcSKumar Kartikeya Dwivedi } 574300f19dcSKumar Kartikeya Dwivedi 575300f19dcSKumar Kartikeya Dwivedi SEC("?tc") 576300f19dcSKumar Kartikeya Dwivedi int pop_back_off(void *ctx) 577300f19dcSKumar Kartikeya Dwivedi { 578300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_back); 579300f19dcSKumar Kartikeya Dwivedi } 580300f19dcSKumar Kartikeya Dwivedi 581300f19dcSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL"; 582