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