104accf79SKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0 204accf79SKumar Kartikeya Dwivedi #include <vmlinux.h> 304accf79SKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h> 404accf79SKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h> 504accf79SKumar Kartikeya Dwivedi #include <bpf/bpf_core_read.h> 6*26c386ecSAndrii Nakryiko #include "bpf_misc.h" 704accf79SKumar Kartikeya Dwivedi 804accf79SKumar Kartikeya Dwivedi struct map_value { 904accf79SKumar Kartikeya Dwivedi char buf[8]; 1004accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc __kptr *unref_ptr; 1104accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc __kptr_ref *ref_ptr; 1204accf79SKumar Kartikeya Dwivedi struct prog_test_member __kptr_ref *ref_memb_ptr; 1304accf79SKumar Kartikeya Dwivedi }; 1404accf79SKumar Kartikeya Dwivedi 1504accf79SKumar Kartikeya Dwivedi struct array_map { 1604accf79SKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_ARRAY); 1704accf79SKumar Kartikeya Dwivedi __type(key, int); 1804accf79SKumar Kartikeya Dwivedi __type(value, struct map_value); 1904accf79SKumar Kartikeya Dwivedi __uint(max_entries, 1); 2004accf79SKumar Kartikeya Dwivedi } array_map SEC(".maps"); 2104accf79SKumar Kartikeya Dwivedi 2204accf79SKumar Kartikeya Dwivedi extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym; 2304accf79SKumar Kartikeya Dwivedi extern struct prog_test_ref_kfunc * 2404accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym; 2504accf79SKumar Kartikeya Dwivedi 2604accf79SKumar Kartikeya Dwivedi SEC("?tc") 27*26c386ecSAndrii Nakryiko __failure __msg("kptr access size must be BPF_DW") 2804accf79SKumar Kartikeya Dwivedi int size_not_bpf_dw(struct __sk_buff *ctx) 2904accf79SKumar Kartikeya Dwivedi { 3004accf79SKumar Kartikeya Dwivedi struct map_value *v; 3104accf79SKumar Kartikeya Dwivedi int key = 0; 3204accf79SKumar Kartikeya Dwivedi 3304accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 3404accf79SKumar Kartikeya Dwivedi if (!v) 3504accf79SKumar Kartikeya Dwivedi return 0; 3604accf79SKumar Kartikeya Dwivedi 3704accf79SKumar Kartikeya Dwivedi *(u32 *)&v->unref_ptr = 0; 3804accf79SKumar Kartikeya Dwivedi return 0; 3904accf79SKumar Kartikeya Dwivedi } 4004accf79SKumar Kartikeya Dwivedi 4104accf79SKumar Kartikeya Dwivedi SEC("?tc") 42*26c386ecSAndrii Nakryiko __failure __msg("kptr access cannot have variable offset") 4304accf79SKumar Kartikeya Dwivedi int non_const_var_off(struct __sk_buff *ctx) 4404accf79SKumar Kartikeya Dwivedi { 4504accf79SKumar Kartikeya Dwivedi struct map_value *v; 4604accf79SKumar Kartikeya Dwivedi int key = 0, id; 4704accf79SKumar Kartikeya Dwivedi 4804accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 4904accf79SKumar Kartikeya Dwivedi if (!v) 5004accf79SKumar Kartikeya Dwivedi return 0; 5104accf79SKumar Kartikeya Dwivedi 5204accf79SKumar Kartikeya Dwivedi id = ctx->protocol; 5304accf79SKumar Kartikeya Dwivedi if (id < 4 || id > 12) 5404accf79SKumar Kartikeya Dwivedi return 0; 5504accf79SKumar Kartikeya Dwivedi *(u64 *)((void *)v + id) = 0; 5604accf79SKumar Kartikeya Dwivedi 5704accf79SKumar Kartikeya Dwivedi return 0; 5804accf79SKumar Kartikeya Dwivedi } 5904accf79SKumar Kartikeya Dwivedi 6004accf79SKumar Kartikeya Dwivedi SEC("?tc") 61*26c386ecSAndrii Nakryiko __failure __msg("R1 doesn't have constant offset. kptr has to be") 6204accf79SKumar Kartikeya Dwivedi int non_const_var_off_kptr_xchg(struct __sk_buff *ctx) 6304accf79SKumar Kartikeya Dwivedi { 6404accf79SKumar Kartikeya Dwivedi struct map_value *v; 6504accf79SKumar Kartikeya Dwivedi int key = 0, id; 6604accf79SKumar Kartikeya Dwivedi 6704accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 6804accf79SKumar Kartikeya Dwivedi if (!v) 6904accf79SKumar Kartikeya Dwivedi return 0; 7004accf79SKumar Kartikeya Dwivedi 7104accf79SKumar Kartikeya Dwivedi id = ctx->protocol; 7204accf79SKumar Kartikeya Dwivedi if (id < 4 || id > 12) 7304accf79SKumar Kartikeya Dwivedi return 0; 7404accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg((void *)v + id, NULL); 7504accf79SKumar Kartikeya Dwivedi 7604accf79SKumar Kartikeya Dwivedi return 0; 7704accf79SKumar Kartikeya Dwivedi } 7804accf79SKumar Kartikeya Dwivedi 7904accf79SKumar Kartikeya Dwivedi SEC("?tc") 80*26c386ecSAndrii Nakryiko __failure __msg("kptr access misaligned expected=8 off=7") 8104accf79SKumar Kartikeya Dwivedi int misaligned_access_write(struct __sk_buff *ctx) 8204accf79SKumar Kartikeya Dwivedi { 8304accf79SKumar Kartikeya Dwivedi struct map_value *v; 8404accf79SKumar Kartikeya Dwivedi int key = 0; 8504accf79SKumar Kartikeya Dwivedi 8604accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 8704accf79SKumar Kartikeya Dwivedi if (!v) 8804accf79SKumar Kartikeya Dwivedi return 0; 8904accf79SKumar Kartikeya Dwivedi 9004accf79SKumar Kartikeya Dwivedi *(void **)((void *)v + 7) = NULL; 9104accf79SKumar Kartikeya Dwivedi 9204accf79SKumar Kartikeya Dwivedi return 0; 9304accf79SKumar Kartikeya Dwivedi } 9404accf79SKumar Kartikeya Dwivedi 9504accf79SKumar Kartikeya Dwivedi SEC("?tc") 96*26c386ecSAndrii Nakryiko __failure __msg("kptr access misaligned expected=8 off=1") 9704accf79SKumar Kartikeya Dwivedi int misaligned_access_read(struct __sk_buff *ctx) 9804accf79SKumar Kartikeya Dwivedi { 9904accf79SKumar Kartikeya Dwivedi struct map_value *v; 10004accf79SKumar Kartikeya Dwivedi int key = 0; 10104accf79SKumar Kartikeya Dwivedi 10204accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 10304accf79SKumar Kartikeya Dwivedi if (!v) 10404accf79SKumar Kartikeya Dwivedi return 0; 10504accf79SKumar Kartikeya Dwivedi 10604accf79SKumar Kartikeya Dwivedi return *(u64 *)((void *)v + 1); 10704accf79SKumar Kartikeya Dwivedi } 10804accf79SKumar Kartikeya Dwivedi 10904accf79SKumar Kartikeya Dwivedi SEC("?tc") 110*26c386ecSAndrii Nakryiko __failure __msg("variable untrusted_ptr_ access var_off=(0x0; 0x1e0)") 11104accf79SKumar Kartikeya Dwivedi int reject_var_off_store(struct __sk_buff *ctx) 11204accf79SKumar Kartikeya Dwivedi { 11304accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *unref_ptr; 11404accf79SKumar Kartikeya Dwivedi struct map_value *v; 11504accf79SKumar Kartikeya Dwivedi int key = 0, id; 11604accf79SKumar Kartikeya Dwivedi 11704accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 11804accf79SKumar Kartikeya Dwivedi if (!v) 11904accf79SKumar Kartikeya Dwivedi return 0; 12004accf79SKumar Kartikeya Dwivedi 12104accf79SKumar Kartikeya Dwivedi unref_ptr = v->unref_ptr; 12204accf79SKumar Kartikeya Dwivedi if (!unref_ptr) 12304accf79SKumar Kartikeya Dwivedi return 0; 12404accf79SKumar Kartikeya Dwivedi id = ctx->protocol; 12504accf79SKumar Kartikeya Dwivedi if (id < 4 || id > 12) 12604accf79SKumar Kartikeya Dwivedi return 0; 12704accf79SKumar Kartikeya Dwivedi unref_ptr += id; 12804accf79SKumar Kartikeya Dwivedi v->unref_ptr = unref_ptr; 12904accf79SKumar Kartikeya Dwivedi 13004accf79SKumar Kartikeya Dwivedi return 0; 13104accf79SKumar Kartikeya Dwivedi } 13204accf79SKumar Kartikeya Dwivedi 13304accf79SKumar Kartikeya Dwivedi SEC("?tc") 134*26c386ecSAndrii Nakryiko __failure __msg("invalid kptr access, R1 type=untrusted_ptr_prog_test_ref_kfunc") 13504accf79SKumar Kartikeya Dwivedi int reject_bad_type_match(struct __sk_buff *ctx) 13604accf79SKumar Kartikeya Dwivedi { 13704accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *unref_ptr; 13804accf79SKumar Kartikeya Dwivedi struct map_value *v; 13904accf79SKumar Kartikeya Dwivedi int key = 0; 14004accf79SKumar Kartikeya Dwivedi 14104accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 14204accf79SKumar Kartikeya Dwivedi if (!v) 14304accf79SKumar Kartikeya Dwivedi return 0; 14404accf79SKumar Kartikeya Dwivedi 14504accf79SKumar Kartikeya Dwivedi unref_ptr = v->unref_ptr; 14604accf79SKumar Kartikeya Dwivedi if (!unref_ptr) 14704accf79SKumar Kartikeya Dwivedi return 0; 14804accf79SKumar Kartikeya Dwivedi unref_ptr = (void *)unref_ptr + 4; 14904accf79SKumar Kartikeya Dwivedi v->unref_ptr = unref_ptr; 15004accf79SKumar Kartikeya Dwivedi 15104accf79SKumar Kartikeya Dwivedi return 0; 15204accf79SKumar Kartikeya Dwivedi } 15304accf79SKumar Kartikeya Dwivedi 15404accf79SKumar Kartikeya Dwivedi SEC("?tc") 155*26c386ecSAndrii Nakryiko __failure __msg("R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_") 15604accf79SKumar Kartikeya Dwivedi int marked_as_untrusted_or_null(struct __sk_buff *ctx) 15704accf79SKumar Kartikeya Dwivedi { 15804accf79SKumar Kartikeya Dwivedi struct map_value *v; 15904accf79SKumar Kartikeya Dwivedi int key = 0; 16004accf79SKumar Kartikeya Dwivedi 16104accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 16204accf79SKumar Kartikeya Dwivedi if (!v) 16304accf79SKumar Kartikeya Dwivedi return 0; 16404accf79SKumar Kartikeya Dwivedi 16504accf79SKumar Kartikeya Dwivedi bpf_this_cpu_ptr(v->unref_ptr); 16604accf79SKumar Kartikeya Dwivedi return 0; 16704accf79SKumar Kartikeya Dwivedi } 16804accf79SKumar Kartikeya Dwivedi 16904accf79SKumar Kartikeya Dwivedi SEC("?tc") 170*26c386ecSAndrii Nakryiko __failure __msg("access beyond struct prog_test_ref_kfunc at off 32 size 4") 17104accf79SKumar Kartikeya Dwivedi int correct_btf_id_check_size(struct __sk_buff *ctx) 17204accf79SKumar Kartikeya Dwivedi { 17304accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 17404accf79SKumar Kartikeya Dwivedi struct map_value *v; 17504accf79SKumar Kartikeya Dwivedi int key = 0; 17604accf79SKumar Kartikeya Dwivedi 17704accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 17804accf79SKumar Kartikeya Dwivedi if (!v) 17904accf79SKumar Kartikeya Dwivedi return 0; 18004accf79SKumar Kartikeya Dwivedi 18104accf79SKumar Kartikeya Dwivedi p = v->unref_ptr; 18204accf79SKumar Kartikeya Dwivedi if (!p) 18304accf79SKumar Kartikeya Dwivedi return 0; 18404accf79SKumar Kartikeya Dwivedi return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc)); 18504accf79SKumar Kartikeya Dwivedi } 18604accf79SKumar Kartikeya Dwivedi 18704accf79SKumar Kartikeya Dwivedi SEC("?tc") 188*26c386ecSAndrii Nakryiko __failure __msg("R1 type=untrusted_ptr_ expected=percpu_ptr_") 18904accf79SKumar Kartikeya Dwivedi int inherit_untrusted_on_walk(struct __sk_buff *ctx) 19004accf79SKumar Kartikeya Dwivedi { 19104accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *unref_ptr; 19204accf79SKumar Kartikeya Dwivedi struct map_value *v; 19304accf79SKumar Kartikeya Dwivedi int key = 0; 19404accf79SKumar Kartikeya Dwivedi 19504accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 19604accf79SKumar Kartikeya Dwivedi if (!v) 19704accf79SKumar Kartikeya Dwivedi return 0; 19804accf79SKumar Kartikeya Dwivedi 19904accf79SKumar Kartikeya Dwivedi unref_ptr = v->unref_ptr; 20004accf79SKumar Kartikeya Dwivedi if (!unref_ptr) 20104accf79SKumar Kartikeya Dwivedi return 0; 20204accf79SKumar Kartikeya Dwivedi unref_ptr = unref_ptr->next; 20304accf79SKumar Kartikeya Dwivedi bpf_this_cpu_ptr(unref_ptr); 20404accf79SKumar Kartikeya Dwivedi return 0; 20504accf79SKumar Kartikeya Dwivedi } 20604accf79SKumar Kartikeya Dwivedi 20704accf79SKumar Kartikeya Dwivedi SEC("?tc") 208*26c386ecSAndrii Nakryiko __failure __msg("off=8 kptr isn't referenced kptr") 20904accf79SKumar Kartikeya Dwivedi int reject_kptr_xchg_on_unref(struct __sk_buff *ctx) 21004accf79SKumar Kartikeya Dwivedi { 21104accf79SKumar Kartikeya Dwivedi struct map_value *v; 21204accf79SKumar Kartikeya Dwivedi int key = 0; 21304accf79SKumar Kartikeya Dwivedi 21404accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 21504accf79SKumar Kartikeya Dwivedi if (!v) 21604accf79SKumar Kartikeya Dwivedi return 0; 21704accf79SKumar Kartikeya Dwivedi 21804accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg(&v->unref_ptr, NULL); 21904accf79SKumar Kartikeya Dwivedi return 0; 22004accf79SKumar Kartikeya Dwivedi } 22104accf79SKumar Kartikeya Dwivedi 22204accf79SKumar Kartikeya Dwivedi SEC("?tc") 223*26c386ecSAndrii Nakryiko __failure __msg("arg#0 expected pointer to map value") 22404accf79SKumar Kartikeya Dwivedi int reject_kptr_get_no_map_val(struct __sk_buff *ctx) 22504accf79SKumar Kartikeya Dwivedi { 22604accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get((void *)&ctx, 0, 0); 22704accf79SKumar Kartikeya Dwivedi return 0; 22804accf79SKumar Kartikeya Dwivedi } 22904accf79SKumar Kartikeya Dwivedi 23004accf79SKumar Kartikeya Dwivedi SEC("?tc") 231*26c386ecSAndrii Nakryiko __failure __msg("arg#0 expected pointer to map value") 23204accf79SKumar Kartikeya Dwivedi int reject_kptr_get_no_null_map_val(struct __sk_buff *ctx) 23304accf79SKumar Kartikeya Dwivedi { 23404accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get(bpf_map_lookup_elem(&array_map, &(int){0}), 0, 0); 23504accf79SKumar Kartikeya Dwivedi return 0; 23604accf79SKumar Kartikeya Dwivedi } 23704accf79SKumar Kartikeya Dwivedi 23804accf79SKumar Kartikeya Dwivedi SEC("?tc") 239*26c386ecSAndrii Nakryiko __failure __msg("arg#0 no referenced kptr at map value offset=0") 24004accf79SKumar Kartikeya Dwivedi int reject_kptr_get_no_kptr(struct __sk_buff *ctx) 24104accf79SKumar Kartikeya Dwivedi { 24204accf79SKumar Kartikeya Dwivedi struct map_value *v; 24304accf79SKumar Kartikeya Dwivedi int key = 0; 24404accf79SKumar Kartikeya Dwivedi 24504accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 24604accf79SKumar Kartikeya Dwivedi if (!v) 24704accf79SKumar Kartikeya Dwivedi return 0; 24804accf79SKumar Kartikeya Dwivedi 24904accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get((void *)v, 0, 0); 25004accf79SKumar Kartikeya Dwivedi return 0; 25104accf79SKumar Kartikeya Dwivedi } 25204accf79SKumar Kartikeya Dwivedi 25304accf79SKumar Kartikeya Dwivedi SEC("?tc") 254*26c386ecSAndrii Nakryiko __failure __msg("arg#0 no referenced kptr at map value offset=8") 25504accf79SKumar Kartikeya Dwivedi int reject_kptr_get_on_unref(struct __sk_buff *ctx) 25604accf79SKumar Kartikeya Dwivedi { 25704accf79SKumar Kartikeya Dwivedi struct map_value *v; 25804accf79SKumar Kartikeya Dwivedi int key = 0; 25904accf79SKumar Kartikeya Dwivedi 26004accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 26104accf79SKumar Kartikeya Dwivedi if (!v) 26204accf79SKumar Kartikeya Dwivedi return 0; 26304accf79SKumar Kartikeya Dwivedi 26404accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get(&v->unref_ptr, 0, 0); 26504accf79SKumar Kartikeya Dwivedi return 0; 26604accf79SKumar Kartikeya Dwivedi } 26704accf79SKumar Kartikeya Dwivedi 26804accf79SKumar Kartikeya Dwivedi SEC("?tc") 269*26c386ecSAndrii Nakryiko __failure __msg("kernel function bpf_kfunc_call_test_kptr_get args#0") 27004accf79SKumar Kartikeya Dwivedi int reject_kptr_get_bad_type_match(struct __sk_buff *ctx) 27104accf79SKumar Kartikeya Dwivedi { 27204accf79SKumar Kartikeya Dwivedi struct map_value *v; 27304accf79SKumar Kartikeya Dwivedi int key = 0; 27404accf79SKumar Kartikeya Dwivedi 27504accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 27604accf79SKumar Kartikeya Dwivedi if (!v) 27704accf79SKumar Kartikeya Dwivedi return 0; 27804accf79SKumar Kartikeya Dwivedi 27904accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get((void *)&v->ref_memb_ptr, 0, 0); 28004accf79SKumar Kartikeya Dwivedi return 0; 28104accf79SKumar Kartikeya Dwivedi } 28204accf79SKumar Kartikeya Dwivedi 28304accf79SKumar Kartikeya Dwivedi SEC("?tc") 284*26c386ecSAndrii Nakryiko __failure __msg("R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_") 28504accf79SKumar Kartikeya Dwivedi int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx) 28604accf79SKumar Kartikeya Dwivedi { 28704accf79SKumar Kartikeya Dwivedi struct map_value *v; 28804accf79SKumar Kartikeya Dwivedi int key = 0; 28904accf79SKumar Kartikeya Dwivedi 29004accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 29104accf79SKumar Kartikeya Dwivedi if (!v) 29204accf79SKumar Kartikeya Dwivedi return 0; 29304accf79SKumar Kartikeya Dwivedi 29404accf79SKumar Kartikeya Dwivedi bpf_this_cpu_ptr(v->ref_ptr); 29504accf79SKumar Kartikeya Dwivedi return 0; 29604accf79SKumar Kartikeya Dwivedi } 29704accf79SKumar Kartikeya Dwivedi 29804accf79SKumar Kartikeya Dwivedi SEC("?tc") 299*26c386ecSAndrii Nakryiko __failure __msg("store to referenced kptr disallowed") 30004accf79SKumar Kartikeya Dwivedi int reject_untrusted_store_to_ref(struct __sk_buff *ctx) 30104accf79SKumar Kartikeya Dwivedi { 30204accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 30304accf79SKumar Kartikeya Dwivedi struct map_value *v; 30404accf79SKumar Kartikeya Dwivedi int key = 0; 30504accf79SKumar Kartikeya Dwivedi 30604accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 30704accf79SKumar Kartikeya Dwivedi if (!v) 30804accf79SKumar Kartikeya Dwivedi return 0; 30904accf79SKumar Kartikeya Dwivedi 31004accf79SKumar Kartikeya Dwivedi p = v->ref_ptr; 31104accf79SKumar Kartikeya Dwivedi if (!p) 31204accf79SKumar Kartikeya Dwivedi return 0; 31304accf79SKumar Kartikeya Dwivedi /* Checkmate, clang */ 31404accf79SKumar Kartikeya Dwivedi *(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p; 31504accf79SKumar Kartikeya Dwivedi return 0; 31604accf79SKumar Kartikeya Dwivedi } 31704accf79SKumar Kartikeya Dwivedi 31804accf79SKumar Kartikeya Dwivedi SEC("?tc") 319*26c386ecSAndrii Nakryiko __failure __msg("R2 type=untrusted_ptr_ expected=ptr_") 32004accf79SKumar Kartikeya Dwivedi int reject_untrusted_xchg(struct __sk_buff *ctx) 32104accf79SKumar Kartikeya Dwivedi { 32204accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 32304accf79SKumar Kartikeya Dwivedi struct map_value *v; 32404accf79SKumar Kartikeya Dwivedi int key = 0; 32504accf79SKumar Kartikeya Dwivedi 32604accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 32704accf79SKumar Kartikeya Dwivedi if (!v) 32804accf79SKumar Kartikeya Dwivedi return 0; 32904accf79SKumar Kartikeya Dwivedi 33004accf79SKumar Kartikeya Dwivedi p = v->ref_ptr; 33104accf79SKumar Kartikeya Dwivedi if (!p) 33204accf79SKumar Kartikeya Dwivedi return 0; 33304accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg(&v->ref_ptr, p); 33404accf79SKumar Kartikeya Dwivedi return 0; 33504accf79SKumar Kartikeya Dwivedi } 33604accf79SKumar Kartikeya Dwivedi 33704accf79SKumar Kartikeya Dwivedi SEC("?tc") 338*26c386ecSAndrii Nakryiko __failure 339*26c386ecSAndrii Nakryiko __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member") 34004accf79SKumar Kartikeya Dwivedi int reject_bad_type_xchg(struct __sk_buff *ctx) 34104accf79SKumar Kartikeya Dwivedi { 34204accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *ref_ptr; 34304accf79SKumar Kartikeya Dwivedi struct map_value *v; 34404accf79SKumar Kartikeya Dwivedi int key = 0; 34504accf79SKumar Kartikeya Dwivedi 34604accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 34704accf79SKumar Kartikeya Dwivedi if (!v) 34804accf79SKumar Kartikeya Dwivedi return 0; 34904accf79SKumar Kartikeya Dwivedi 35004accf79SKumar Kartikeya Dwivedi ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 35104accf79SKumar Kartikeya Dwivedi if (!ref_ptr) 35204accf79SKumar Kartikeya Dwivedi return 0; 35304accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr); 35404accf79SKumar Kartikeya Dwivedi return 0; 35504accf79SKumar Kartikeya Dwivedi } 35604accf79SKumar Kartikeya Dwivedi 35704accf79SKumar Kartikeya Dwivedi SEC("?tc") 358*26c386ecSAndrii Nakryiko __failure __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc") 35904accf79SKumar Kartikeya Dwivedi int reject_member_of_ref_xchg(struct __sk_buff *ctx) 36004accf79SKumar Kartikeya Dwivedi { 36104accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *ref_ptr; 36204accf79SKumar Kartikeya Dwivedi struct map_value *v; 36304accf79SKumar Kartikeya Dwivedi int key = 0; 36404accf79SKumar Kartikeya Dwivedi 36504accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 36604accf79SKumar Kartikeya Dwivedi if (!v) 36704accf79SKumar Kartikeya Dwivedi return 0; 36804accf79SKumar Kartikeya Dwivedi 36904accf79SKumar Kartikeya Dwivedi ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 37004accf79SKumar Kartikeya Dwivedi if (!ref_ptr) 37104accf79SKumar Kartikeya Dwivedi return 0; 37204accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb); 37304accf79SKumar Kartikeya Dwivedi return 0; 37404accf79SKumar Kartikeya Dwivedi } 37504accf79SKumar Kartikeya Dwivedi 37604accf79SKumar Kartikeya Dwivedi SEC("?syscall") 377*26c386ecSAndrii Nakryiko __failure __msg("kptr cannot be accessed indirectly by helper") 37804accf79SKumar Kartikeya Dwivedi int reject_indirect_helper_access(struct __sk_buff *ctx) 37904accf79SKumar Kartikeya Dwivedi { 38004accf79SKumar Kartikeya Dwivedi struct map_value *v; 38104accf79SKumar Kartikeya Dwivedi int key = 0; 38204accf79SKumar Kartikeya Dwivedi 38304accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 38404accf79SKumar Kartikeya Dwivedi if (!v) 38504accf79SKumar Kartikeya Dwivedi return 0; 38604accf79SKumar Kartikeya Dwivedi 38704accf79SKumar Kartikeya Dwivedi bpf_get_current_comm(v, sizeof(v->buf) + 1); 38804accf79SKumar Kartikeya Dwivedi return 0; 38904accf79SKumar Kartikeya Dwivedi } 39004accf79SKumar Kartikeya Dwivedi 39104accf79SKumar Kartikeya Dwivedi __noinline 39204accf79SKumar Kartikeya Dwivedi int write_func(int *p) 39304accf79SKumar Kartikeya Dwivedi { 39404accf79SKumar Kartikeya Dwivedi return p ? *p = 42 : 0; 39504accf79SKumar Kartikeya Dwivedi } 39604accf79SKumar Kartikeya Dwivedi 39704accf79SKumar Kartikeya Dwivedi SEC("?tc") 398*26c386ecSAndrii Nakryiko __failure __msg("kptr cannot be accessed indirectly by helper") 39904accf79SKumar Kartikeya Dwivedi int reject_indirect_global_func_access(struct __sk_buff *ctx) 40004accf79SKumar Kartikeya Dwivedi { 40104accf79SKumar Kartikeya Dwivedi struct map_value *v; 40204accf79SKumar Kartikeya Dwivedi int key = 0; 40304accf79SKumar Kartikeya Dwivedi 40404accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 40504accf79SKumar Kartikeya Dwivedi if (!v) 40604accf79SKumar Kartikeya Dwivedi return 0; 40704accf79SKumar Kartikeya Dwivedi 40804accf79SKumar Kartikeya Dwivedi return write_func((void *)v + 5); 40904accf79SKumar Kartikeya Dwivedi } 41004accf79SKumar Kartikeya Dwivedi 41104accf79SKumar Kartikeya Dwivedi SEC("?tc") 412*26c386ecSAndrii Nakryiko __failure __msg("Unreleased reference id=5 alloc_insn=") 41304accf79SKumar Kartikeya Dwivedi int kptr_xchg_ref_state(struct __sk_buff *ctx) 41404accf79SKumar Kartikeya Dwivedi { 41504accf79SKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p; 41604accf79SKumar Kartikeya Dwivedi struct map_value *v; 41704accf79SKumar Kartikeya Dwivedi int key = 0; 41804accf79SKumar Kartikeya Dwivedi 41904accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 42004accf79SKumar Kartikeya Dwivedi if (!v) 42104accf79SKumar Kartikeya Dwivedi return 0; 42204accf79SKumar Kartikeya Dwivedi 42304accf79SKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); 42404accf79SKumar Kartikeya Dwivedi if (!p) 42504accf79SKumar Kartikeya Dwivedi return 0; 42604accf79SKumar Kartikeya Dwivedi bpf_kptr_xchg(&v->ref_ptr, p); 42704accf79SKumar Kartikeya Dwivedi return 0; 42804accf79SKumar Kartikeya Dwivedi } 42904accf79SKumar Kartikeya Dwivedi 43004accf79SKumar Kartikeya Dwivedi SEC("?tc") 431*26c386ecSAndrii Nakryiko __failure __msg("Unreleased reference id=3 alloc_insn=") 43204accf79SKumar Kartikeya Dwivedi int kptr_get_ref_state(struct __sk_buff *ctx) 43304accf79SKumar Kartikeya Dwivedi { 43404accf79SKumar Kartikeya Dwivedi struct map_value *v; 43504accf79SKumar Kartikeya Dwivedi int key = 0; 43604accf79SKumar Kartikeya Dwivedi 43704accf79SKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &key); 43804accf79SKumar Kartikeya Dwivedi if (!v) 43904accf79SKumar Kartikeya Dwivedi return 0; 44004accf79SKumar Kartikeya Dwivedi 44104accf79SKumar Kartikeya Dwivedi bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0); 44204accf79SKumar Kartikeya Dwivedi return 0; 44304accf79SKumar Kartikeya Dwivedi } 44404accf79SKumar Kartikeya Dwivedi 44504accf79SKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL"; 446