1 // SPDX-License-Identifier: GPL-2.0 2 #include <vmlinux.h> 3 #include <bpf/bpf_tracing.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_core_read.h> 6 7 struct map_value { 8 char buf[8]; 9 struct prog_test_ref_kfunc __kptr *unref_ptr; 10 struct prog_test_ref_kfunc __kptr_ref *ref_ptr; 11 struct prog_test_member __kptr_ref *ref_memb_ptr; 12 }; 13 14 struct array_map { 15 __uint(type, BPF_MAP_TYPE_ARRAY); 16 __type(key, int); 17 __type(value, struct map_value); 18 __uint(max_entries, 1); 19 } array_map SEC(".maps"); 20 21 extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym; 22 extern struct prog_test_ref_kfunc * 23 bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym; 24 25 SEC("?tc") 26 int size_not_bpf_dw(struct __sk_buff *ctx) 27 { 28 struct map_value *v; 29 int key = 0; 30 31 v = bpf_map_lookup_elem(&array_map, &key); 32 if (!v) 33 return 0; 34 35 *(u32 *)&v->unref_ptr = 0; 36 return 0; 37 } 38 39 SEC("?tc") 40 int non_const_var_off(struct __sk_buff *ctx) 41 { 42 struct map_value *v; 43 int key = 0, id; 44 45 v = bpf_map_lookup_elem(&array_map, &key); 46 if (!v) 47 return 0; 48 49 id = ctx->protocol; 50 if (id < 4 || id > 12) 51 return 0; 52 *(u64 *)((void *)v + id) = 0; 53 54 return 0; 55 } 56 57 SEC("?tc") 58 int non_const_var_off_kptr_xchg(struct __sk_buff *ctx) 59 { 60 struct map_value *v; 61 int key = 0, id; 62 63 v = bpf_map_lookup_elem(&array_map, &key); 64 if (!v) 65 return 0; 66 67 id = ctx->protocol; 68 if (id < 4 || id > 12) 69 return 0; 70 bpf_kptr_xchg((void *)v + id, NULL); 71 72 return 0; 73 } 74 75 SEC("?tc") 76 int misaligned_access_write(struct __sk_buff *ctx) 77 { 78 struct map_value *v; 79 int key = 0; 80 81 v = bpf_map_lookup_elem(&array_map, &key); 82 if (!v) 83 return 0; 84 85 *(void **)((void *)v + 7) = NULL; 86 87 return 0; 88 } 89 90 SEC("?tc") 91 int misaligned_access_read(struct __sk_buff *ctx) 92 { 93 struct map_value *v; 94 int key = 0; 95 96 v = bpf_map_lookup_elem(&array_map, &key); 97 if (!v) 98 return 0; 99 100 return *(u64 *)((void *)v + 1); 101 } 102 103 SEC("?tc") 104 int reject_var_off_store(struct __sk_buff *ctx) 105 { 106 struct prog_test_ref_kfunc *unref_ptr; 107 struct map_value *v; 108 int key = 0, id; 109 110 v = bpf_map_lookup_elem(&array_map, &key); 111 if (!v) 112 return 0; 113 114 unref_ptr = v->unref_ptr; 115 if (!unref_ptr) 116 return 0; 117 id = ctx->protocol; 118 if (id < 4 || id > 12) 119 return 0; 120 unref_ptr += id; 121 v->unref_ptr = unref_ptr; 122 123 return 0; 124 } 125 126 SEC("?tc") 127 int reject_bad_type_match(struct __sk_buff *ctx) 128 { 129 struct prog_test_ref_kfunc *unref_ptr; 130 struct map_value *v; 131 int key = 0; 132 133 v = bpf_map_lookup_elem(&array_map, &key); 134 if (!v) 135 return 0; 136 137 unref_ptr = v->unref_ptr; 138 if (!unref_ptr) 139 return 0; 140 unref_ptr = (void *)unref_ptr + 4; 141 v->unref_ptr = unref_ptr; 142 143 return 0; 144 } 145 146 SEC("?tc") 147 int marked_as_untrusted_or_null(struct __sk_buff *ctx) 148 { 149 struct map_value *v; 150 int key = 0; 151 152 v = bpf_map_lookup_elem(&array_map, &key); 153 if (!v) 154 return 0; 155 156 bpf_this_cpu_ptr(v->unref_ptr); 157 return 0; 158 } 159 160 SEC("?tc") 161 int correct_btf_id_check_size(struct __sk_buff *ctx) 162 { 163 struct prog_test_ref_kfunc *p; 164 struct map_value *v; 165 int key = 0; 166 167 v = bpf_map_lookup_elem(&array_map, &key); 168 if (!v) 169 return 0; 170 171 p = v->unref_ptr; 172 if (!p) 173 return 0; 174 return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc)); 175 } 176 177 SEC("?tc") 178 int inherit_untrusted_on_walk(struct __sk_buff *ctx) 179 { 180 struct prog_test_ref_kfunc *unref_ptr; 181 struct map_value *v; 182 int key = 0; 183 184 v = bpf_map_lookup_elem(&array_map, &key); 185 if (!v) 186 return 0; 187 188 unref_ptr = v->unref_ptr; 189 if (!unref_ptr) 190 return 0; 191 unref_ptr = unref_ptr->next; 192 bpf_this_cpu_ptr(unref_ptr); 193 return 0; 194 } 195 196 SEC("?tc") 197 int reject_kptr_xchg_on_unref(struct __sk_buff *ctx) 198 { 199 struct map_value *v; 200 int key = 0; 201 202 v = bpf_map_lookup_elem(&array_map, &key); 203 if (!v) 204 return 0; 205 206 bpf_kptr_xchg(&v->unref_ptr, NULL); 207 return 0; 208 } 209 210 SEC("?tc") 211 int reject_kptr_get_no_map_val(struct __sk_buff *ctx) 212 { 213 bpf_kfunc_call_test_kptr_get((void *)&ctx, 0, 0); 214 return 0; 215 } 216 217 SEC("?tc") 218 int reject_kptr_get_no_null_map_val(struct __sk_buff *ctx) 219 { 220 bpf_kfunc_call_test_kptr_get(bpf_map_lookup_elem(&array_map, &(int){0}), 0, 0); 221 return 0; 222 } 223 224 SEC("?tc") 225 int reject_kptr_get_no_kptr(struct __sk_buff *ctx) 226 { 227 struct map_value *v; 228 int key = 0; 229 230 v = bpf_map_lookup_elem(&array_map, &key); 231 if (!v) 232 return 0; 233 234 bpf_kfunc_call_test_kptr_get((void *)v, 0, 0); 235 return 0; 236 } 237 238 SEC("?tc") 239 int reject_kptr_get_on_unref(struct __sk_buff *ctx) 240 { 241 struct map_value *v; 242 int key = 0; 243 244 v = bpf_map_lookup_elem(&array_map, &key); 245 if (!v) 246 return 0; 247 248 bpf_kfunc_call_test_kptr_get(&v->unref_ptr, 0, 0); 249 return 0; 250 } 251 252 SEC("?tc") 253 int reject_kptr_get_bad_type_match(struct __sk_buff *ctx) 254 { 255 struct map_value *v; 256 int key = 0; 257 258 v = bpf_map_lookup_elem(&array_map, &key); 259 if (!v) 260 return 0; 261 262 bpf_kfunc_call_test_kptr_get((void *)&v->ref_memb_ptr, 0, 0); 263 return 0; 264 } 265 266 SEC("?tc") 267 int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx) 268 { 269 struct map_value *v; 270 int key = 0; 271 272 v = bpf_map_lookup_elem(&array_map, &key); 273 if (!v) 274 return 0; 275 276 bpf_this_cpu_ptr(v->ref_ptr); 277 return 0; 278 } 279 280 SEC("?tc") 281 int reject_untrusted_store_to_ref(struct __sk_buff *ctx) 282 { 283 struct prog_test_ref_kfunc *p; 284 struct map_value *v; 285 int key = 0; 286 287 v = bpf_map_lookup_elem(&array_map, &key); 288 if (!v) 289 return 0; 290 291 p = v->ref_ptr; 292 if (!p) 293 return 0; 294 /* Checkmate, clang */ 295 *(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p; 296 return 0; 297 } 298 299 SEC("?tc") 300 int reject_untrusted_xchg(struct __sk_buff *ctx) 301 { 302 struct prog_test_ref_kfunc *p; 303 struct map_value *v; 304 int key = 0; 305 306 v = bpf_map_lookup_elem(&array_map, &key); 307 if (!v) 308 return 0; 309 310 p = v->ref_ptr; 311 if (!p) 312 return 0; 313 bpf_kptr_xchg(&v->ref_ptr, p); 314 return 0; 315 } 316 317 SEC("?tc") 318 int reject_bad_type_xchg(struct __sk_buff *ctx) 319 { 320 struct prog_test_ref_kfunc *ref_ptr; 321 struct map_value *v; 322 int key = 0; 323 324 v = bpf_map_lookup_elem(&array_map, &key); 325 if (!v) 326 return 0; 327 328 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 329 if (!ref_ptr) 330 return 0; 331 bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr); 332 return 0; 333 } 334 335 SEC("?tc") 336 int reject_member_of_ref_xchg(struct __sk_buff *ctx) 337 { 338 struct prog_test_ref_kfunc *ref_ptr; 339 struct map_value *v; 340 int key = 0; 341 342 v = bpf_map_lookup_elem(&array_map, &key); 343 if (!v) 344 return 0; 345 346 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 347 if (!ref_ptr) 348 return 0; 349 bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb); 350 return 0; 351 } 352 353 SEC("?syscall") 354 int reject_indirect_helper_access(struct __sk_buff *ctx) 355 { 356 struct map_value *v; 357 int key = 0; 358 359 v = bpf_map_lookup_elem(&array_map, &key); 360 if (!v) 361 return 0; 362 363 bpf_get_current_comm(v, sizeof(v->buf) + 1); 364 return 0; 365 } 366 367 __noinline 368 int write_func(int *p) 369 { 370 return p ? *p = 42 : 0; 371 } 372 373 SEC("?tc") 374 int reject_indirect_global_func_access(struct __sk_buff *ctx) 375 { 376 struct map_value *v; 377 int key = 0; 378 379 v = bpf_map_lookup_elem(&array_map, &key); 380 if (!v) 381 return 0; 382 383 return write_func((void *)v + 5); 384 } 385 386 SEC("?tc") 387 int kptr_xchg_ref_state(struct __sk_buff *ctx) 388 { 389 struct prog_test_ref_kfunc *p; 390 struct map_value *v; 391 int key = 0; 392 393 v = bpf_map_lookup_elem(&array_map, &key); 394 if (!v) 395 return 0; 396 397 p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 398 if (!p) 399 return 0; 400 bpf_kptr_xchg(&v->ref_ptr, p); 401 return 0; 402 } 403 404 SEC("?tc") 405 int kptr_get_ref_state(struct __sk_buff *ctx) 406 { 407 struct map_value *v; 408 int key = 0; 409 410 v = bpf_map_lookup_elem(&array_map, &key); 411 if (!v) 412 return 0; 413 414 bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0); 415 return 0; 416 } 417 418 char _license[] SEC("license") = "GPL"; 419