12cbc469aSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0 22cbc469aSKumar Kartikeya Dwivedi #include <vmlinux.h> 32cbc469aSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h> 42cbc469aSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h> 52cbc469aSKumar Kartikeya Dwivedi 62cbc469aSKumar Kartikeya Dwivedi struct map_value { 7*03b77e17SAlexei Starovoitov struct prog_test_ref_kfunc __kptr_untrusted *unref_ptr; 8*03b77e17SAlexei Starovoitov struct prog_test_ref_kfunc __kptr *ref_ptr; 92cbc469aSKumar Kartikeya Dwivedi }; 102cbc469aSKumar Kartikeya Dwivedi 112cbc469aSKumar Kartikeya Dwivedi struct array_map { 122cbc469aSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_ARRAY); 132cbc469aSKumar Kartikeya Dwivedi __type(key, int); 142cbc469aSKumar Kartikeya Dwivedi __type(value, struct map_value); 152cbc469aSKumar Kartikeya Dwivedi __uint(max_entries, 1); 162cbc469aSKumar Kartikeya Dwivedi } array_map SEC(".maps"); 172cbc469aSKumar Kartikeya Dwivedi 1885521e1eSKumar Kartikeya Dwivedi struct pcpu_array_map { 1985521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 2085521e1eSKumar Kartikeya Dwivedi __type(key, int); 2185521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 2285521e1eSKumar Kartikeya Dwivedi __uint(max_entries, 1); 2385521e1eSKumar Kartikeya Dwivedi } pcpu_array_map SEC(".maps"); 2485521e1eSKumar Kartikeya Dwivedi 252cbc469aSKumar Kartikeya Dwivedi struct hash_map { 262cbc469aSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_HASH); 272cbc469aSKumar Kartikeya Dwivedi __type(key, int); 282cbc469aSKumar Kartikeya Dwivedi __type(value, struct map_value); 292cbc469aSKumar Kartikeya Dwivedi __uint(max_entries, 1); 302cbc469aSKumar Kartikeya Dwivedi } hash_map SEC(".maps"); 312cbc469aSKumar Kartikeya Dwivedi 3285521e1eSKumar Kartikeya Dwivedi struct pcpu_hash_map { 3385521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 3485521e1eSKumar Kartikeya Dwivedi __type(key, int); 3585521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 3685521e1eSKumar Kartikeya Dwivedi __uint(max_entries, 1); 3785521e1eSKumar Kartikeya Dwivedi } pcpu_hash_map SEC(".maps"); 3885521e1eSKumar Kartikeya Dwivedi 392cbc469aSKumar Kartikeya Dwivedi struct hash_malloc_map { 402cbc469aSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_HASH); 412cbc469aSKumar Kartikeya Dwivedi __type(key, int); 422cbc469aSKumar Kartikeya Dwivedi __type(value, struct map_value); 432cbc469aSKumar Kartikeya Dwivedi __uint(max_entries, 1); 442cbc469aSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 452cbc469aSKumar Kartikeya Dwivedi } hash_malloc_map SEC(".maps"); 462cbc469aSKumar Kartikeya Dwivedi 4785521e1eSKumar Kartikeya Dwivedi struct pcpu_hash_malloc_map { 4885521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 4985521e1eSKumar Kartikeya Dwivedi __type(key, int); 5085521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 5185521e1eSKumar Kartikeya Dwivedi __uint(max_entries, 1); 5285521e1eSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 5385521e1eSKumar Kartikeya Dwivedi } pcpu_hash_malloc_map SEC(".maps"); 5485521e1eSKumar Kartikeya Dwivedi 552cbc469aSKumar Kartikeya Dwivedi struct lru_hash_map { 562cbc469aSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_LRU_HASH); 572cbc469aSKumar Kartikeya Dwivedi __type(key, int); 582cbc469aSKumar Kartikeya Dwivedi __type(value, struct map_value); 592cbc469aSKumar Kartikeya Dwivedi __uint(max_entries, 1); 602cbc469aSKumar Kartikeya Dwivedi } lru_hash_map SEC(".maps"); 612cbc469aSKumar Kartikeya Dwivedi 6285521e1eSKumar Kartikeya Dwivedi struct lru_pcpu_hash_map { 6385521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_LRU_PERCPU_HASH); 6485521e1eSKumar Kartikeya Dwivedi __type(key, int); 6585521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 6685521e1eSKumar Kartikeya Dwivedi __uint(max_entries, 1); 6785521e1eSKumar Kartikeya Dwivedi } lru_pcpu_hash_map SEC(".maps"); 6885521e1eSKumar Kartikeya Dwivedi 6985521e1eSKumar Kartikeya Dwivedi struct cgrp_ls_map { 7085521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_CGRP_STORAGE); 7185521e1eSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 7285521e1eSKumar Kartikeya Dwivedi __type(key, int); 7385521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 7485521e1eSKumar Kartikeya Dwivedi } cgrp_ls_map SEC(".maps"); 7585521e1eSKumar Kartikeya Dwivedi 7685521e1eSKumar Kartikeya Dwivedi struct task_ls_map { 7785521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_TASK_STORAGE); 7885521e1eSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 7985521e1eSKumar Kartikeya Dwivedi __type(key, int); 8085521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 8185521e1eSKumar Kartikeya Dwivedi } task_ls_map SEC(".maps"); 8285521e1eSKumar Kartikeya Dwivedi 8385521e1eSKumar Kartikeya Dwivedi struct inode_ls_map { 8485521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_INODE_STORAGE); 8585521e1eSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 8685521e1eSKumar Kartikeya Dwivedi __type(key, int); 8785521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 8885521e1eSKumar Kartikeya Dwivedi } inode_ls_map SEC(".maps"); 8985521e1eSKumar Kartikeya Dwivedi 9085521e1eSKumar Kartikeya Dwivedi struct sk_ls_map { 9185521e1eSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_SK_STORAGE); 9285521e1eSKumar Kartikeya Dwivedi __uint(map_flags, BPF_F_NO_PREALLOC); 9385521e1eSKumar Kartikeya Dwivedi __type(key, int); 9485521e1eSKumar Kartikeya Dwivedi __type(value, struct map_value); 9585521e1eSKumar Kartikeya Dwivedi } sk_ls_map SEC(".maps"); 9685521e1eSKumar Kartikeya Dwivedi 972cbc469aSKumar Kartikeya Dwivedi #define DEFINE_MAP_OF_MAP(map_type, inner_map_type, name) \ 982cbc469aSKumar Kartikeya Dwivedi struct { \ 992cbc469aSKumar Kartikeya Dwivedi __uint(type, map_type); \ 1002cbc469aSKumar Kartikeya Dwivedi __uint(max_entries, 1); \ 1012cbc469aSKumar Kartikeya Dwivedi __uint(key_size, sizeof(int)); \ 1022cbc469aSKumar Kartikeya Dwivedi __uint(value_size, sizeof(int)); \ 1032cbc469aSKumar Kartikeya Dwivedi __array(values, struct inner_map_type); \ 1042cbc469aSKumar Kartikeya Dwivedi } name SEC(".maps") = { \ 1052cbc469aSKumar Kartikeya Dwivedi .values = { [0] = &inner_map_type }, \ 1062cbc469aSKumar Kartikeya Dwivedi } 1072cbc469aSKumar Kartikeya Dwivedi 1082cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_map, array_of_array_maps); 1092cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_ARRAY_OF_MAPS, hash_map, array_of_hash_maps); 1102cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_ARRAY_OF_MAPS, hash_malloc_map, array_of_hash_malloc_maps); 1112cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_ARRAY_OF_MAPS, lru_hash_map, array_of_lru_hash_maps); 1122cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_HASH_OF_MAPS, array_map, hash_of_array_maps); 1132cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_HASH_OF_MAPS, hash_map, hash_of_hash_maps); 1142cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_HASH_OF_MAPS, hash_malloc_map, hash_of_hash_malloc_maps); 1152cbc469aSKumar Kartikeya Dwivedi DEFINE_MAP_OF_MAP(BPF_MAP_TYPE_HASH_OF_MAPS, lru_hash_map, hash_of_lru_hash_maps); 1162cbc469aSKumar Kartikeya Dwivedi 1172cbc469aSKumar Kartikeya Dwivedi extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym; 1182cbc469aSKumar Kartikeya Dwivedi extern struct prog_test_ref_kfunc * 1192cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym; 1202cbc469aSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p) __ksym; 1212cbc469aSKumar Kartikeya Dwivedi 12262d101d5SAlexei Starovoitov #define WRITE_ONCE(x, val) ((*(volatile typeof(x) *) &(x)) = (val)) 12362d101d5SAlexei Starovoitov 1242cbc469aSKumar Kartikeya Dwivedi static void test_kptr_unref(struct map_value *v) 1252cbc469aSKumar Kartikeya Dwivedi { 1262cbc469aSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 1272cbc469aSKumar Kartikeya Dwivedi 1282cbc469aSKumar Kartikeya Dwivedi p = v->unref_ptr; 1292cbc469aSKumar Kartikeya Dwivedi /* store untrusted_ptr_or_null_ */ 13062d101d5SAlexei Starovoitov WRITE_ONCE(v->unref_ptr, p); 1312cbc469aSKumar Kartikeya Dwivedi if (!p) 1322cbc469aSKumar Kartikeya Dwivedi return; 1332cbc469aSKumar Kartikeya Dwivedi if (p->a + p->b > 100) 1342cbc469aSKumar Kartikeya Dwivedi return; 1352cbc469aSKumar Kartikeya Dwivedi /* store untrusted_ptr_ */ 13662d101d5SAlexei Starovoitov WRITE_ONCE(v->unref_ptr, p); 1372cbc469aSKumar Kartikeya Dwivedi /* store NULL */ 13862d101d5SAlexei Starovoitov WRITE_ONCE(v->unref_ptr, NULL); 1392cbc469aSKumar Kartikeya Dwivedi } 1402cbc469aSKumar Kartikeya Dwivedi 1412cbc469aSKumar Kartikeya Dwivedi static void test_kptr_ref(struct map_value *v) 1422cbc469aSKumar Kartikeya Dwivedi { 1432cbc469aSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 1442cbc469aSKumar Kartikeya Dwivedi 1452cbc469aSKumar Kartikeya Dwivedi p = v->ref_ptr; 1462cbc469aSKumar Kartikeya Dwivedi /* store ptr_or_null_ */ 14762d101d5SAlexei Starovoitov WRITE_ONCE(v->unref_ptr, p); 1482cbc469aSKumar Kartikeya Dwivedi if (!p) 1492cbc469aSKumar Kartikeya Dwivedi return; 1502cbc469aSKumar Kartikeya Dwivedi if (p->a + p->b > 100) 1512cbc469aSKumar Kartikeya Dwivedi return; 1522cbc469aSKumar Kartikeya Dwivedi /* store NULL */ 1532cbc469aSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, NULL); 1542cbc469aSKumar Kartikeya Dwivedi if (!p) 1552cbc469aSKumar Kartikeya Dwivedi return; 1562cbc469aSKumar Kartikeya Dwivedi if (p->a + p->b > 100) { 1572cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1582cbc469aSKumar Kartikeya Dwivedi return; 1592cbc469aSKumar Kartikeya Dwivedi } 1602cbc469aSKumar Kartikeya Dwivedi /* store ptr_ */ 16162d101d5SAlexei Starovoitov WRITE_ONCE(v->unref_ptr, p); 1622cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1632cbc469aSKumar Kartikeya Dwivedi 1642cbc469aSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 1652cbc469aSKumar Kartikeya Dwivedi if (!p) 1662cbc469aSKumar Kartikeya Dwivedi return; 1672cbc469aSKumar Kartikeya Dwivedi /* store ptr_ */ 1682cbc469aSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, p); 1692cbc469aSKumar Kartikeya Dwivedi if (!p) 1702cbc469aSKumar Kartikeya Dwivedi return; 1712cbc469aSKumar Kartikeya Dwivedi if (p->a + p->b > 100) { 1722cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1732cbc469aSKumar Kartikeya Dwivedi return; 1742cbc469aSKumar Kartikeya Dwivedi } 1752cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1762cbc469aSKumar Kartikeya Dwivedi } 1772cbc469aSKumar Kartikeya Dwivedi 1782cbc469aSKumar Kartikeya Dwivedi static void test_kptr_get(struct map_value *v) 1792cbc469aSKumar Kartikeya Dwivedi { 1802cbc469aSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 1812cbc469aSKumar Kartikeya Dwivedi 1822cbc469aSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0); 1832cbc469aSKumar Kartikeya Dwivedi if (!p) 1842cbc469aSKumar Kartikeya Dwivedi return; 1852cbc469aSKumar Kartikeya Dwivedi if (p->a + p->b > 100) { 1862cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1872cbc469aSKumar Kartikeya Dwivedi return; 1882cbc469aSKumar Kartikeya Dwivedi } 1892cbc469aSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 1902cbc469aSKumar Kartikeya Dwivedi } 1912cbc469aSKumar Kartikeya Dwivedi 1922cbc469aSKumar Kartikeya Dwivedi static void test_kptr(struct map_value *v) 1932cbc469aSKumar Kartikeya Dwivedi { 1942cbc469aSKumar Kartikeya Dwivedi test_kptr_unref(v); 1952cbc469aSKumar Kartikeya Dwivedi test_kptr_ref(v); 1962cbc469aSKumar Kartikeya Dwivedi test_kptr_get(v); 1972cbc469aSKumar Kartikeya Dwivedi } 1982cbc469aSKumar Kartikeya Dwivedi 1992cbc469aSKumar Kartikeya Dwivedi SEC("tc") 2002cbc469aSKumar Kartikeya Dwivedi int test_map_kptr(struct __sk_buff *ctx) 2012cbc469aSKumar Kartikeya Dwivedi { 2022cbc469aSKumar Kartikeya Dwivedi struct map_value *v; 2030ef6740eSKumar Kartikeya Dwivedi int key = 0; 2042cbc469aSKumar Kartikeya Dwivedi 2052cbc469aSKumar Kartikeya Dwivedi #define TEST(map) \ 2062cbc469aSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&map, &key); \ 2072cbc469aSKumar Kartikeya Dwivedi if (!v) \ 2082cbc469aSKumar Kartikeya Dwivedi return 0; \ 2092cbc469aSKumar Kartikeya Dwivedi test_kptr(v) 2102cbc469aSKumar Kartikeya Dwivedi 2112cbc469aSKumar Kartikeya Dwivedi TEST(array_map); 2122cbc469aSKumar Kartikeya Dwivedi TEST(hash_map); 2132cbc469aSKumar Kartikeya Dwivedi TEST(hash_malloc_map); 2142cbc469aSKumar Kartikeya Dwivedi TEST(lru_hash_map); 2152cbc469aSKumar Kartikeya Dwivedi 2162cbc469aSKumar Kartikeya Dwivedi #undef TEST 2172cbc469aSKumar Kartikeya Dwivedi return 0; 2182cbc469aSKumar Kartikeya Dwivedi } 2192cbc469aSKumar Kartikeya Dwivedi 22085521e1eSKumar Kartikeya Dwivedi SEC("tp_btf/cgroup_mkdir") 22185521e1eSKumar Kartikeya Dwivedi int BPF_PROG(test_cgrp_map_kptr, struct cgroup *cgrp, const char *path) 22285521e1eSKumar Kartikeya Dwivedi { 22385521e1eSKumar Kartikeya Dwivedi struct map_value *v; 22485521e1eSKumar Kartikeya Dwivedi 22585521e1eSKumar Kartikeya Dwivedi v = bpf_cgrp_storage_get(&cgrp_ls_map, cgrp, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); 22685521e1eSKumar Kartikeya Dwivedi if (v) 22785521e1eSKumar Kartikeya Dwivedi test_kptr(v); 22885521e1eSKumar Kartikeya Dwivedi return 0; 22985521e1eSKumar Kartikeya Dwivedi } 23085521e1eSKumar Kartikeya Dwivedi 23185521e1eSKumar Kartikeya Dwivedi SEC("lsm/inode_unlink") 23285521e1eSKumar Kartikeya Dwivedi int BPF_PROG(test_task_map_kptr, struct inode *inode, struct dentry *victim) 23385521e1eSKumar Kartikeya Dwivedi { 23485521e1eSKumar Kartikeya Dwivedi struct task_struct *task; 23585521e1eSKumar Kartikeya Dwivedi struct map_value *v; 23685521e1eSKumar Kartikeya Dwivedi 23785521e1eSKumar Kartikeya Dwivedi task = bpf_get_current_task_btf(); 23885521e1eSKumar Kartikeya Dwivedi if (!task) 23985521e1eSKumar Kartikeya Dwivedi return 0; 24085521e1eSKumar Kartikeya Dwivedi v = bpf_task_storage_get(&task_ls_map, task, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); 24185521e1eSKumar Kartikeya Dwivedi if (v) 24285521e1eSKumar Kartikeya Dwivedi test_kptr(v); 24385521e1eSKumar Kartikeya Dwivedi return 0; 24485521e1eSKumar Kartikeya Dwivedi } 24585521e1eSKumar Kartikeya Dwivedi 24685521e1eSKumar Kartikeya Dwivedi SEC("lsm/inode_unlink") 24785521e1eSKumar Kartikeya Dwivedi int BPF_PROG(test_inode_map_kptr, struct inode *inode, struct dentry *victim) 24885521e1eSKumar Kartikeya Dwivedi { 24985521e1eSKumar Kartikeya Dwivedi struct map_value *v; 25085521e1eSKumar Kartikeya Dwivedi 25185521e1eSKumar Kartikeya Dwivedi v = bpf_inode_storage_get(&inode_ls_map, inode, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); 25285521e1eSKumar Kartikeya Dwivedi if (v) 25385521e1eSKumar Kartikeya Dwivedi test_kptr(v); 25485521e1eSKumar Kartikeya Dwivedi return 0; 25585521e1eSKumar Kartikeya Dwivedi } 25685521e1eSKumar Kartikeya Dwivedi 25785521e1eSKumar Kartikeya Dwivedi SEC("tc") 25885521e1eSKumar Kartikeya Dwivedi int test_sk_map_kptr(struct __sk_buff *ctx) 25985521e1eSKumar Kartikeya Dwivedi { 26085521e1eSKumar Kartikeya Dwivedi struct map_value *v; 26185521e1eSKumar Kartikeya Dwivedi struct bpf_sock *sk; 26285521e1eSKumar Kartikeya Dwivedi 26385521e1eSKumar Kartikeya Dwivedi sk = ctx->sk; 26485521e1eSKumar Kartikeya Dwivedi if (!sk) 26585521e1eSKumar Kartikeya Dwivedi return 0; 26685521e1eSKumar Kartikeya Dwivedi v = bpf_sk_storage_get(&sk_ls_map, sk, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); 26785521e1eSKumar Kartikeya Dwivedi if (v) 26885521e1eSKumar Kartikeya Dwivedi test_kptr(v); 26985521e1eSKumar Kartikeya Dwivedi return 0; 27085521e1eSKumar Kartikeya Dwivedi } 27185521e1eSKumar Kartikeya Dwivedi 2722cbc469aSKumar Kartikeya Dwivedi SEC("tc") 2732cbc469aSKumar Kartikeya Dwivedi int test_map_in_map_kptr(struct __sk_buff *ctx) 2742cbc469aSKumar Kartikeya Dwivedi { 2752cbc469aSKumar Kartikeya Dwivedi struct map_value *v; 2760ef6740eSKumar Kartikeya Dwivedi int key = 0; 2772cbc469aSKumar Kartikeya Dwivedi void *map; 2782cbc469aSKumar Kartikeya Dwivedi 2792cbc469aSKumar Kartikeya Dwivedi #define TEST(map_in_map) \ 2802cbc469aSKumar Kartikeya Dwivedi map = bpf_map_lookup_elem(&map_in_map, &key); \ 2812cbc469aSKumar Kartikeya Dwivedi if (!map) \ 2822cbc469aSKumar Kartikeya Dwivedi return 0; \ 2832cbc469aSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(map, &key); \ 2842cbc469aSKumar Kartikeya Dwivedi if (!v) \ 2852cbc469aSKumar Kartikeya Dwivedi return 0; \ 2862cbc469aSKumar Kartikeya Dwivedi test_kptr(v) 2872cbc469aSKumar Kartikeya Dwivedi 2882cbc469aSKumar Kartikeya Dwivedi TEST(array_of_array_maps); 2892cbc469aSKumar Kartikeya Dwivedi TEST(array_of_hash_maps); 2902cbc469aSKumar Kartikeya Dwivedi TEST(array_of_hash_malloc_maps); 2912cbc469aSKumar Kartikeya Dwivedi TEST(array_of_lru_hash_maps); 2922cbc469aSKumar Kartikeya Dwivedi TEST(hash_of_array_maps); 2932cbc469aSKumar Kartikeya Dwivedi TEST(hash_of_hash_maps); 2942cbc469aSKumar Kartikeya Dwivedi TEST(hash_of_hash_malloc_maps); 2952cbc469aSKumar Kartikeya Dwivedi TEST(hash_of_lru_hash_maps); 2962cbc469aSKumar Kartikeya Dwivedi 2972cbc469aSKumar Kartikeya Dwivedi #undef TEST 2982cbc469aSKumar Kartikeya Dwivedi return 0; 2992cbc469aSKumar Kartikeya Dwivedi } 3002cbc469aSKumar Kartikeya Dwivedi 30185521e1eSKumar Kartikeya Dwivedi int ref = 1; 30285521e1eSKumar Kartikeya Dwivedi 30385521e1eSKumar Kartikeya Dwivedi static __always_inline 30485521e1eSKumar Kartikeya Dwivedi int test_map_kptr_ref_pre(struct map_value *v) 3050ef6740eSKumar Kartikeya Dwivedi { 3060ef6740eSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p, *p_st; 3070ef6740eSKumar Kartikeya Dwivedi unsigned long arg = 0; 30885521e1eSKumar Kartikeya Dwivedi int ret; 3090ef6740eSKumar Kartikeya Dwivedi 3100ef6740eSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&arg); 3110ef6740eSKumar Kartikeya Dwivedi if (!p) 3120ef6740eSKumar Kartikeya Dwivedi return 1; 31385521e1eSKumar Kartikeya Dwivedi ref++; 3140ef6740eSKumar Kartikeya Dwivedi 3150ef6740eSKumar Kartikeya Dwivedi p_st = p->next; 31685521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) { 3170ef6740eSKumar Kartikeya Dwivedi ret = 2; 3180ef6740eSKumar Kartikeya Dwivedi goto end; 3190ef6740eSKumar Kartikeya Dwivedi } 3200ef6740eSKumar Kartikeya Dwivedi 32185521e1eSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, p); 32285521e1eSKumar Kartikeya Dwivedi if (p) { 3230ef6740eSKumar Kartikeya Dwivedi ret = 3; 3240ef6740eSKumar Kartikeya Dwivedi goto end; 3250ef6740eSKumar Kartikeya Dwivedi } 32685521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) 32785521e1eSKumar Kartikeya Dwivedi return 4; 3280ef6740eSKumar Kartikeya Dwivedi 3290ef6740eSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0); 3300ef6740eSKumar Kartikeya Dwivedi if (!p) 33185521e1eSKumar Kartikeya Dwivedi return 5; 33285521e1eSKumar Kartikeya Dwivedi ref++; 33385521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) { 33485521e1eSKumar Kartikeya Dwivedi ret = 6; 3350ef6740eSKumar Kartikeya Dwivedi goto end; 3360ef6740eSKumar Kartikeya Dwivedi } 3370ef6740eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 33885521e1eSKumar Kartikeya Dwivedi ref--; 33985521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) 34085521e1eSKumar Kartikeya Dwivedi return 7; 3410ef6740eSKumar Kartikeya Dwivedi 3420ef6740eSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, NULL); 3430ef6740eSKumar Kartikeya Dwivedi if (!p) 34485521e1eSKumar Kartikeya Dwivedi return 8; 3450ef6740eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 34685521e1eSKumar Kartikeya Dwivedi ref--; 34785521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) 34885521e1eSKumar Kartikeya Dwivedi return 9; 3490ef6740eSKumar Kartikeya Dwivedi 3500ef6740eSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&arg); 3510ef6740eSKumar Kartikeya Dwivedi if (!p) 35285521e1eSKumar Kartikeya Dwivedi return 10; 35385521e1eSKumar Kartikeya Dwivedi ref++; 3540ef6740eSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, p); 3550ef6740eSKumar Kartikeya Dwivedi if (p) { 35685521e1eSKumar Kartikeya Dwivedi ret = 11; 3570ef6740eSKumar Kartikeya Dwivedi goto end; 3580ef6740eSKumar Kartikeya Dwivedi } 35985521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) 36085521e1eSKumar Kartikeya Dwivedi return 12; 3610ef6740eSKumar Kartikeya Dwivedi /* Leave in map */ 3620ef6740eSKumar Kartikeya Dwivedi 3630ef6740eSKumar Kartikeya Dwivedi return 0; 3640ef6740eSKumar Kartikeya Dwivedi end: 36585521e1eSKumar Kartikeya Dwivedi ref--; 3660ef6740eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 3670ef6740eSKumar Kartikeya Dwivedi return ret; 3680ef6740eSKumar Kartikeya Dwivedi } 3690ef6740eSKumar Kartikeya Dwivedi 37085521e1eSKumar Kartikeya Dwivedi static __always_inline 37185521e1eSKumar Kartikeya Dwivedi int test_map_kptr_ref_post(struct map_value *v) 3720ef6740eSKumar Kartikeya Dwivedi { 3730ef6740eSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p, *p_st; 3740ef6740eSKumar Kartikeya Dwivedi 3750ef6740eSKumar Kartikeya Dwivedi p_st = v->ref_ptr; 37685521e1eSKumar Kartikeya Dwivedi if (!p_st || p_st->cnt.refs.counter != ref) 37785521e1eSKumar Kartikeya Dwivedi return 1; 3780ef6740eSKumar Kartikeya Dwivedi 3790ef6740eSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, NULL); 3800ef6740eSKumar Kartikeya Dwivedi if (!p) 38185521e1eSKumar Kartikeya Dwivedi return 2; 38285521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) { 3830ef6740eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 38485521e1eSKumar Kartikeya Dwivedi return 3; 3850ef6740eSKumar Kartikeya Dwivedi } 3860ef6740eSKumar Kartikeya Dwivedi 3870ef6740eSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ref_ptr, p); 3880ef6740eSKumar Kartikeya Dwivedi if (p) { 3890ef6740eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 39085521e1eSKumar Kartikeya Dwivedi return 4; 3910ef6740eSKumar Kartikeya Dwivedi } 39285521e1eSKumar Kartikeya Dwivedi if (p_st->cnt.refs.counter != ref) 39385521e1eSKumar Kartikeya Dwivedi return 5; 3940ef6740eSKumar Kartikeya Dwivedi 3950ef6740eSKumar Kartikeya Dwivedi return 0; 3960ef6740eSKumar Kartikeya Dwivedi } 3970ef6740eSKumar Kartikeya Dwivedi 39885521e1eSKumar Kartikeya Dwivedi #define TEST(map) \ 39985521e1eSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&map, &key); \ 40085521e1eSKumar Kartikeya Dwivedi if (!v) \ 40185521e1eSKumar Kartikeya Dwivedi return -1; \ 40285521e1eSKumar Kartikeya Dwivedi ret = test_map_kptr_ref_pre(v); \ 40385521e1eSKumar Kartikeya Dwivedi if (ret) \ 40485521e1eSKumar Kartikeya Dwivedi return ret; 40585521e1eSKumar Kartikeya Dwivedi 40685521e1eSKumar Kartikeya Dwivedi #define TEST_PCPU(map) \ 40785521e1eSKumar Kartikeya Dwivedi v = bpf_map_lookup_percpu_elem(&map, &key, 0); \ 40885521e1eSKumar Kartikeya Dwivedi if (!v) \ 40985521e1eSKumar Kartikeya Dwivedi return -1; \ 41085521e1eSKumar Kartikeya Dwivedi ret = test_map_kptr_ref_pre(v); \ 41185521e1eSKumar Kartikeya Dwivedi if (ret) \ 41285521e1eSKumar Kartikeya Dwivedi return ret; 41385521e1eSKumar Kartikeya Dwivedi 41485521e1eSKumar Kartikeya Dwivedi SEC("tc") 41585521e1eSKumar Kartikeya Dwivedi int test_map_kptr_ref1(struct __sk_buff *ctx) 41685521e1eSKumar Kartikeya Dwivedi { 41785521e1eSKumar Kartikeya Dwivedi struct map_value *v, val = {}; 41885521e1eSKumar Kartikeya Dwivedi int key = 0, ret; 41985521e1eSKumar Kartikeya Dwivedi 42085521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&hash_map, &key, &val, 0); 42185521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&hash_malloc_map, &key, &val, 0); 42285521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&lru_hash_map, &key, &val, 0); 42385521e1eSKumar Kartikeya Dwivedi 42485521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&pcpu_hash_map, &key, &val, 0); 42585521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&pcpu_hash_malloc_map, &key, &val, 0); 42685521e1eSKumar Kartikeya Dwivedi bpf_map_update_elem(&lru_pcpu_hash_map, &key, &val, 0); 42785521e1eSKumar Kartikeya Dwivedi 42885521e1eSKumar Kartikeya Dwivedi TEST(array_map); 42985521e1eSKumar Kartikeya Dwivedi TEST(hash_map); 43085521e1eSKumar Kartikeya Dwivedi TEST(hash_malloc_map); 43185521e1eSKumar Kartikeya Dwivedi TEST(lru_hash_map); 43285521e1eSKumar Kartikeya Dwivedi 43385521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_array_map); 43485521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_hash_map); 43585521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_hash_malloc_map); 43685521e1eSKumar Kartikeya Dwivedi TEST_PCPU(lru_pcpu_hash_map); 43785521e1eSKumar Kartikeya Dwivedi 43885521e1eSKumar Kartikeya Dwivedi return 0; 43985521e1eSKumar Kartikeya Dwivedi } 44085521e1eSKumar Kartikeya Dwivedi 44185521e1eSKumar Kartikeya Dwivedi #undef TEST 44285521e1eSKumar Kartikeya Dwivedi #undef TEST_PCPU 44385521e1eSKumar Kartikeya Dwivedi 44485521e1eSKumar Kartikeya Dwivedi #define TEST(map) \ 44585521e1eSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&map, &key); \ 44685521e1eSKumar Kartikeya Dwivedi if (!v) \ 44785521e1eSKumar Kartikeya Dwivedi return -1; \ 44885521e1eSKumar Kartikeya Dwivedi ret = test_map_kptr_ref_post(v); \ 44985521e1eSKumar Kartikeya Dwivedi if (ret) \ 45085521e1eSKumar Kartikeya Dwivedi return ret; 45185521e1eSKumar Kartikeya Dwivedi 45285521e1eSKumar Kartikeya Dwivedi #define TEST_PCPU(map) \ 45385521e1eSKumar Kartikeya Dwivedi v = bpf_map_lookup_percpu_elem(&map, &key, 0); \ 45485521e1eSKumar Kartikeya Dwivedi if (!v) \ 45585521e1eSKumar Kartikeya Dwivedi return -1; \ 45685521e1eSKumar Kartikeya Dwivedi ret = test_map_kptr_ref_post(v); \ 45785521e1eSKumar Kartikeya Dwivedi if (ret) \ 45885521e1eSKumar Kartikeya Dwivedi return ret; 45985521e1eSKumar Kartikeya Dwivedi 46085521e1eSKumar Kartikeya Dwivedi SEC("tc") 46185521e1eSKumar Kartikeya Dwivedi int test_map_kptr_ref2(struct __sk_buff *ctx) 46285521e1eSKumar Kartikeya Dwivedi { 46385521e1eSKumar Kartikeya Dwivedi struct map_value *v; 46485521e1eSKumar Kartikeya Dwivedi int key = 0, ret; 46585521e1eSKumar Kartikeya Dwivedi 46685521e1eSKumar Kartikeya Dwivedi TEST(array_map); 46785521e1eSKumar Kartikeya Dwivedi TEST(hash_map); 46885521e1eSKumar Kartikeya Dwivedi TEST(hash_malloc_map); 46985521e1eSKumar Kartikeya Dwivedi TEST(lru_hash_map); 47085521e1eSKumar Kartikeya Dwivedi 47185521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_array_map); 47285521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_hash_map); 47385521e1eSKumar Kartikeya Dwivedi TEST_PCPU(pcpu_hash_malloc_map); 47485521e1eSKumar Kartikeya Dwivedi TEST_PCPU(lru_pcpu_hash_map); 47585521e1eSKumar Kartikeya Dwivedi 47685521e1eSKumar Kartikeya Dwivedi return 0; 47785521e1eSKumar Kartikeya Dwivedi } 47885521e1eSKumar Kartikeya Dwivedi 47985521e1eSKumar Kartikeya Dwivedi #undef TEST 48085521e1eSKumar Kartikeya Dwivedi #undef TEST_PCPU 48185521e1eSKumar Kartikeya Dwivedi 48285521e1eSKumar Kartikeya Dwivedi SEC("tc") 48385521e1eSKumar Kartikeya Dwivedi int test_map_kptr_ref3(struct __sk_buff *ctx) 48485521e1eSKumar Kartikeya Dwivedi { 48585521e1eSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 48685521e1eSKumar Kartikeya Dwivedi unsigned long sp = 0; 48785521e1eSKumar Kartikeya Dwivedi 48885521e1eSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&sp); 48985521e1eSKumar Kartikeya Dwivedi if (!p) 49085521e1eSKumar Kartikeya Dwivedi return 1; 49185521e1eSKumar Kartikeya Dwivedi ref++; 49285521e1eSKumar Kartikeya Dwivedi if (p->cnt.refs.counter != ref) { 49385521e1eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 49485521e1eSKumar Kartikeya Dwivedi return 2; 49585521e1eSKumar Kartikeya Dwivedi } 49685521e1eSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p); 49785521e1eSKumar Kartikeya Dwivedi ref--; 49885521e1eSKumar Kartikeya Dwivedi return 0; 49985521e1eSKumar Kartikeya Dwivedi } 50085521e1eSKumar Kartikeya Dwivedi 50185521e1eSKumar Kartikeya Dwivedi SEC("syscall") 50285521e1eSKumar Kartikeya Dwivedi int test_ls_map_kptr_ref1(void *ctx) 50385521e1eSKumar Kartikeya Dwivedi { 50485521e1eSKumar Kartikeya Dwivedi struct task_struct *current; 50585521e1eSKumar Kartikeya Dwivedi struct map_value *v; 50685521e1eSKumar Kartikeya Dwivedi int ret; 50785521e1eSKumar Kartikeya Dwivedi 50885521e1eSKumar Kartikeya Dwivedi current = bpf_get_current_task_btf(); 50985521e1eSKumar Kartikeya Dwivedi if (!current) 51085521e1eSKumar Kartikeya Dwivedi return 100; 51185521e1eSKumar Kartikeya Dwivedi v = bpf_task_storage_get(&task_ls_map, current, NULL, 0); 51285521e1eSKumar Kartikeya Dwivedi if (v) 51385521e1eSKumar Kartikeya Dwivedi return 150; 51485521e1eSKumar Kartikeya Dwivedi v = bpf_task_storage_get(&task_ls_map, current, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); 51585521e1eSKumar Kartikeya Dwivedi if (!v) 51685521e1eSKumar Kartikeya Dwivedi return 200; 51785521e1eSKumar Kartikeya Dwivedi return test_map_kptr_ref_pre(v); 51885521e1eSKumar Kartikeya Dwivedi } 51985521e1eSKumar Kartikeya Dwivedi 52085521e1eSKumar Kartikeya Dwivedi SEC("syscall") 52185521e1eSKumar Kartikeya Dwivedi int test_ls_map_kptr_ref2(void *ctx) 52285521e1eSKumar Kartikeya Dwivedi { 52385521e1eSKumar Kartikeya Dwivedi struct task_struct *current; 52485521e1eSKumar Kartikeya Dwivedi struct map_value *v; 52585521e1eSKumar Kartikeya Dwivedi int ret; 52685521e1eSKumar Kartikeya Dwivedi 52785521e1eSKumar Kartikeya Dwivedi current = bpf_get_current_task_btf(); 52885521e1eSKumar Kartikeya Dwivedi if (!current) 52985521e1eSKumar Kartikeya Dwivedi return 100; 53085521e1eSKumar Kartikeya Dwivedi v = bpf_task_storage_get(&task_ls_map, current, NULL, 0); 53185521e1eSKumar Kartikeya Dwivedi if (!v) 53285521e1eSKumar Kartikeya Dwivedi return 200; 53385521e1eSKumar Kartikeya Dwivedi return test_map_kptr_ref_post(v); 53485521e1eSKumar Kartikeya Dwivedi } 53585521e1eSKumar Kartikeya Dwivedi 53685521e1eSKumar Kartikeya Dwivedi SEC("syscall") 53785521e1eSKumar Kartikeya Dwivedi int test_ls_map_kptr_ref_del(void *ctx) 53885521e1eSKumar Kartikeya Dwivedi { 53985521e1eSKumar Kartikeya Dwivedi struct task_struct *current; 54085521e1eSKumar Kartikeya Dwivedi struct map_value *v; 54185521e1eSKumar Kartikeya Dwivedi int ret; 54285521e1eSKumar Kartikeya Dwivedi 54385521e1eSKumar Kartikeya Dwivedi current = bpf_get_current_task_btf(); 54485521e1eSKumar Kartikeya Dwivedi if (!current) 54585521e1eSKumar Kartikeya Dwivedi return 100; 54685521e1eSKumar Kartikeya Dwivedi v = bpf_task_storage_get(&task_ls_map, current, NULL, 0); 54785521e1eSKumar Kartikeya Dwivedi if (!v) 54885521e1eSKumar Kartikeya Dwivedi return 200; 54985521e1eSKumar Kartikeya Dwivedi if (!v->ref_ptr) 55085521e1eSKumar Kartikeya Dwivedi return 300; 55185521e1eSKumar Kartikeya Dwivedi return bpf_task_storage_delete(&task_ls_map, current); 55285521e1eSKumar Kartikeya Dwivedi } 55385521e1eSKumar Kartikeya Dwivedi 5542cbc469aSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL"; 555