Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 197 lines 4.0 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ 3#include <vmlinux.h> 4#include <bpf/bpf_helpers.h> 5#include <bpf/bpf_tracing.h> 6#include "../test_kmods/bpf_testmod_kfunc.h" 7 8struct map_value { 9 struct prog_test_ref_kfunc __kptr *ref_ptr; 10}; 11 12struct { 13 __uint(type, BPF_MAP_TYPE_HASH); 14 __uint(map_flags, BPF_F_NO_PREALLOC); 15 __type(key, int); 16 __type(value, struct map_value); 17 __uint(max_entries, 1); 18} race_hash_map SEC(".maps"); 19 20struct { 21 __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 22 __uint(map_flags, BPF_F_NO_PREALLOC); 23 __type(key, int); 24 __type(value, struct map_value); 25 __uint(max_entries, 1); 26} race_percpu_hash_map SEC(".maps"); 27 28struct { 29 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 30 __uint(map_flags, BPF_F_NO_PREALLOC); 31 __type(key, int); 32 __type(value, struct map_value); 33} race_sk_ls_map SEC(".maps"); 34 35int num_of_refs; 36int sk_ls_leak_done; 37int target_map_id; 38int map_freed; 39const volatile int nr_cpus; 40 41SEC("tc") 42int test_htab_leak(struct __sk_buff *skb) 43{ 44 struct prog_test_ref_kfunc *p, *old; 45 struct map_value val = {}; 46 struct map_value *v; 47 int key = 0; 48 49 if (bpf_map_update_elem(&race_hash_map, &key, &val, BPF_ANY)) 50 return 1; 51 52 v = bpf_map_lookup_elem(&race_hash_map, &key); 53 if (!v) 54 return 2; 55 56 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 57 if (!p) 58 return 3; 59 old = bpf_kptr_xchg(&v->ref_ptr, p); 60 if (old) 61 bpf_kfunc_call_test_release(old); 62 63 bpf_map_delete_elem(&race_hash_map, &key); 64 65 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 66 if (!p) 67 return 4; 68 old = bpf_kptr_xchg(&v->ref_ptr, p); 69 if (old) 70 bpf_kfunc_call_test_release(old); 71 72 return 0; 73} 74 75static int fill_percpu_kptr(struct map_value *v) 76{ 77 struct prog_test_ref_kfunc *p, *old; 78 79 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 80 if (!p) 81 return 1; 82 old = bpf_kptr_xchg(&v->ref_ptr, p); 83 if (old) 84 bpf_kfunc_call_test_release(old); 85 return 0; 86} 87 88SEC("tc") 89int test_percpu_htab_leak(struct __sk_buff *skb) 90{ 91 struct map_value *v, *arr[16] = {}; 92 struct map_value val = {}; 93 int key = 0; 94 int err = 0; 95 96 if (bpf_map_update_elem(&race_percpu_hash_map, &key, &val, BPF_ANY)) 97 return 1; 98 99 for (int i = 0; i < nr_cpus; i++) { 100 v = bpf_map_lookup_percpu_elem(&race_percpu_hash_map, &key, i); 101 if (!v) 102 return 2; 103 arr[i] = v; 104 } 105 106 bpf_map_delete_elem(&race_percpu_hash_map, &key); 107 108 for (int i = 0; i < nr_cpus; i++) { 109 v = arr[i]; 110 err = fill_percpu_kptr(v); 111 if (err) 112 return 3; 113 } 114 115 return 0; 116} 117 118SEC("tp_btf/inet_sock_set_state") 119int BPF_PROG(test_sk_ls_leak, struct sock *sk, int oldstate, int newstate) 120{ 121 struct prog_test_ref_kfunc *p, *old; 122 struct map_value *v; 123 124 if (newstate != BPF_TCP_SYN_SENT) 125 return 0; 126 127 if (sk_ls_leak_done) 128 return 0; 129 130 v = bpf_sk_storage_get(&race_sk_ls_map, sk, NULL, 131 BPF_SK_STORAGE_GET_F_CREATE); 132 if (!v) 133 return 0; 134 135 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 136 if (!p) 137 return 0; 138 old = bpf_kptr_xchg(&v->ref_ptr, p); 139 if (old) 140 bpf_kfunc_call_test_release(old); 141 142 bpf_sk_storage_delete(&race_sk_ls_map, sk); 143 144 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 145 if (!p) 146 return 0; 147 old = bpf_kptr_xchg(&v->ref_ptr, p); 148 if (old) 149 bpf_kfunc_call_test_release(old); 150 151 sk_ls_leak_done = 1; 152 return 0; 153} 154 155long target_map_ptr; 156 157SEC("fentry/bpf_map_put") 158int BPF_PROG(map_put, struct bpf_map *map) 159{ 160 if (target_map_id && map->id == (u32)target_map_id) 161 target_map_ptr = (long)map; 162 return 0; 163} 164 165SEC("fexit/htab_map_free") 166int BPF_PROG(htab_map_free, struct bpf_map *map) 167{ 168 if (target_map_ptr && (long)map == target_map_ptr) 169 map_freed = 1; 170 return 0; 171} 172 173SEC("fexit/bpf_sk_storage_map_free") 174int BPF_PROG(sk_map_free, struct bpf_map *map) 175{ 176 if (target_map_ptr && (long)map == target_map_ptr) 177 map_freed = 1; 178 return 0; 179} 180 181SEC("syscall") 182int count_ref(void *ctx) 183{ 184 struct prog_test_ref_kfunc *p; 185 unsigned long arg = 0; 186 187 p = bpf_kfunc_call_test_acquire(&arg); 188 if (!p) 189 return 1; 190 191 num_of_refs = p->cnt.refs.counter; 192 193 bpf_kfunc_call_test_release(p); 194 return 0; 195} 196 197char _license[] SEC("license") = "GPL";