map_kptr_fail.c (7352B)
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 7struct 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 14struct 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 21extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym; 22extern struct prog_test_ref_kfunc * 23bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym; 24 25SEC("?tc") 26int 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 39SEC("?tc") 40int 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 57SEC("?tc") 58int 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 75SEC("?tc") 76int 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 90SEC("?tc") 91int 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 103SEC("?tc") 104int 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 126SEC("?tc") 127int 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 146SEC("?tc") 147int 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 160SEC("?tc") 161int 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 177SEC("?tc") 178int 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 196SEC("?tc") 197int 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 210SEC("?tc") 211int 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 217SEC("?tc") 218int 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 224SEC("?tc") 225int 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 238SEC("?tc") 239int 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 252SEC("?tc") 253int 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 266SEC("?tc") 267int 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 280SEC("?tc") 281int 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 299SEC("?tc") 300int 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 317SEC("?tc") 318int 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 335SEC("?tc") 336int 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 353SEC("?syscall") 354int 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 368int write_func(int *p) 369{ 370 return p ? *p = 42 : 0; 371} 372 373SEC("?tc") 374int 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 386SEC("?tc") 387int 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 404SEC("?tc") 405int 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 418char _license[] SEC("license") = "GPL";