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>
626c386ecSAndrii Nakryiko #include "bpf_misc.h"
7*8e9af821SJiri Olsa #include "../bpf_testmod/bpf_testmod_kfunc.h"
804accf79SKumar Kartikeya Dwivedi 
904accf79SKumar Kartikeya Dwivedi struct map_value {
1004accf79SKumar Kartikeya Dwivedi 	char buf[8];
1103b77e17SAlexei Starovoitov 	struct prog_test_ref_kfunc __kptr_untrusted *unref_ptr;
1203b77e17SAlexei Starovoitov 	struct prog_test_ref_kfunc __kptr *ref_ptr;
1303b77e17SAlexei Starovoitov 	struct prog_test_member __kptr *ref_memb_ptr;
1404accf79SKumar Kartikeya Dwivedi };
1504accf79SKumar Kartikeya Dwivedi 
1604accf79SKumar Kartikeya Dwivedi struct array_map {
1704accf79SKumar Kartikeya Dwivedi 	__uint(type, BPF_MAP_TYPE_ARRAY);
1804accf79SKumar Kartikeya Dwivedi 	__type(key, int);
1904accf79SKumar Kartikeya Dwivedi 	__type(value, struct map_value);
2004accf79SKumar Kartikeya Dwivedi 	__uint(max_entries, 1);
2104accf79SKumar Kartikeya Dwivedi } array_map SEC(".maps");
2204accf79SKumar Kartikeya Dwivedi 
2304accf79SKumar Kartikeya Dwivedi SEC("?tc")
2426c386ecSAndrii Nakryiko __failure __msg("kptr access size must be BPF_DW")
size_not_bpf_dw(struct __sk_buff * ctx)2504accf79SKumar Kartikeya Dwivedi int size_not_bpf_dw(struct __sk_buff *ctx)
2604accf79SKumar Kartikeya Dwivedi {
2704accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
2804accf79SKumar Kartikeya Dwivedi 	int key = 0;
2904accf79SKumar Kartikeya Dwivedi 
3004accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
3104accf79SKumar Kartikeya Dwivedi 	if (!v)
3204accf79SKumar Kartikeya Dwivedi 		return 0;
3304accf79SKumar Kartikeya Dwivedi 
3404accf79SKumar Kartikeya Dwivedi 	*(u32 *)&v->unref_ptr = 0;
3504accf79SKumar Kartikeya Dwivedi 	return 0;
3604accf79SKumar Kartikeya Dwivedi }
3704accf79SKumar Kartikeya Dwivedi 
3804accf79SKumar Kartikeya Dwivedi SEC("?tc")
3926c386ecSAndrii Nakryiko __failure __msg("kptr access cannot have variable offset")
non_const_var_off(struct __sk_buff * ctx)4004accf79SKumar Kartikeya Dwivedi int non_const_var_off(struct __sk_buff *ctx)
4104accf79SKumar Kartikeya Dwivedi {
4204accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
4304accf79SKumar Kartikeya Dwivedi 	int key = 0, id;
4404accf79SKumar Kartikeya Dwivedi 
4504accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
4604accf79SKumar Kartikeya Dwivedi 	if (!v)
4704accf79SKumar Kartikeya Dwivedi 		return 0;
4804accf79SKumar Kartikeya Dwivedi 
4904accf79SKumar Kartikeya Dwivedi 	id = ctx->protocol;
5004accf79SKumar Kartikeya Dwivedi 	if (id < 4 || id > 12)
5104accf79SKumar Kartikeya Dwivedi 		return 0;
5204accf79SKumar Kartikeya Dwivedi 	*(u64 *)((void *)v + id) = 0;
5304accf79SKumar Kartikeya Dwivedi 
5404accf79SKumar Kartikeya Dwivedi 	return 0;
5504accf79SKumar Kartikeya Dwivedi }
5604accf79SKumar Kartikeya Dwivedi 
5704accf79SKumar Kartikeya Dwivedi SEC("?tc")
5826c386ecSAndrii Nakryiko __failure __msg("R1 doesn't have constant offset. kptr has to be")
non_const_var_off_kptr_xchg(struct __sk_buff * ctx)5904accf79SKumar Kartikeya Dwivedi int non_const_var_off_kptr_xchg(struct __sk_buff *ctx)
6004accf79SKumar Kartikeya Dwivedi {
6104accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
6204accf79SKumar Kartikeya Dwivedi 	int key = 0, id;
6304accf79SKumar Kartikeya Dwivedi 
6404accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
6504accf79SKumar Kartikeya Dwivedi 	if (!v)
6604accf79SKumar Kartikeya Dwivedi 		return 0;
6704accf79SKumar Kartikeya Dwivedi 
6804accf79SKumar Kartikeya Dwivedi 	id = ctx->protocol;
6904accf79SKumar Kartikeya Dwivedi 	if (id < 4 || id > 12)
7004accf79SKumar Kartikeya Dwivedi 		return 0;
7104accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg((void *)v + id, NULL);
7204accf79SKumar Kartikeya Dwivedi 
7304accf79SKumar Kartikeya Dwivedi 	return 0;
7404accf79SKumar Kartikeya Dwivedi }
7504accf79SKumar Kartikeya Dwivedi 
7604accf79SKumar Kartikeya Dwivedi SEC("?tc")
7726c386ecSAndrii Nakryiko __failure __msg("kptr access misaligned expected=8 off=7")
misaligned_access_write(struct __sk_buff * ctx)7804accf79SKumar Kartikeya Dwivedi int misaligned_access_write(struct __sk_buff *ctx)
7904accf79SKumar Kartikeya Dwivedi {
8004accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
8104accf79SKumar Kartikeya Dwivedi 	int key = 0;
8204accf79SKumar Kartikeya Dwivedi 
8304accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
8404accf79SKumar Kartikeya Dwivedi 	if (!v)
8504accf79SKumar Kartikeya Dwivedi 		return 0;
8604accf79SKumar Kartikeya Dwivedi 
8704accf79SKumar Kartikeya Dwivedi 	*(void **)((void *)v + 7) = NULL;
8804accf79SKumar Kartikeya Dwivedi 
8904accf79SKumar Kartikeya Dwivedi 	return 0;
9004accf79SKumar Kartikeya Dwivedi }
9104accf79SKumar Kartikeya Dwivedi 
9204accf79SKumar Kartikeya Dwivedi SEC("?tc")
9326c386ecSAndrii Nakryiko __failure __msg("kptr access misaligned expected=8 off=1")
misaligned_access_read(struct __sk_buff * ctx)9404accf79SKumar Kartikeya Dwivedi int misaligned_access_read(struct __sk_buff *ctx)
9504accf79SKumar Kartikeya Dwivedi {
9604accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
9704accf79SKumar Kartikeya Dwivedi 	int key = 0;
9804accf79SKumar Kartikeya Dwivedi 
9904accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
10004accf79SKumar Kartikeya Dwivedi 	if (!v)
10104accf79SKumar Kartikeya Dwivedi 		return 0;
10204accf79SKumar Kartikeya Dwivedi 
10304accf79SKumar Kartikeya Dwivedi 	return *(u64 *)((void *)v + 1);
10404accf79SKumar Kartikeya Dwivedi }
10504accf79SKumar Kartikeya Dwivedi 
10604accf79SKumar Kartikeya Dwivedi SEC("?tc")
10726c386ecSAndrii Nakryiko __failure __msg("variable untrusted_ptr_ access var_off=(0x0; 0x1e0)")
reject_var_off_store(struct __sk_buff * ctx)10804accf79SKumar Kartikeya Dwivedi int reject_var_off_store(struct __sk_buff *ctx)
10904accf79SKumar Kartikeya Dwivedi {
11004accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *unref_ptr;
11104accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
11204accf79SKumar Kartikeya Dwivedi 	int key = 0, id;
11304accf79SKumar Kartikeya Dwivedi 
11404accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
11504accf79SKumar Kartikeya Dwivedi 	if (!v)
11604accf79SKumar Kartikeya Dwivedi 		return 0;
11704accf79SKumar Kartikeya Dwivedi 
11804accf79SKumar Kartikeya Dwivedi 	unref_ptr = v->unref_ptr;
11904accf79SKumar Kartikeya Dwivedi 	if (!unref_ptr)
12004accf79SKumar Kartikeya Dwivedi 		return 0;
12104accf79SKumar Kartikeya Dwivedi 	id = ctx->protocol;
12204accf79SKumar Kartikeya Dwivedi 	if (id < 4 || id > 12)
12304accf79SKumar Kartikeya Dwivedi 		return 0;
12404accf79SKumar Kartikeya Dwivedi 	unref_ptr += id;
12504accf79SKumar Kartikeya Dwivedi 	v->unref_ptr = unref_ptr;
12604accf79SKumar Kartikeya Dwivedi 
12704accf79SKumar Kartikeya Dwivedi 	return 0;
12804accf79SKumar Kartikeya Dwivedi }
12904accf79SKumar Kartikeya Dwivedi 
13004accf79SKumar Kartikeya Dwivedi SEC("?tc")
13126c386ecSAndrii Nakryiko __failure __msg("invalid kptr access, R1 type=untrusted_ptr_prog_test_ref_kfunc")
reject_bad_type_match(struct __sk_buff * ctx)13204accf79SKumar Kartikeya Dwivedi int reject_bad_type_match(struct __sk_buff *ctx)
13304accf79SKumar Kartikeya Dwivedi {
13404accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *unref_ptr;
13504accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
13604accf79SKumar Kartikeya Dwivedi 	int key = 0;
13704accf79SKumar Kartikeya Dwivedi 
13804accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
13904accf79SKumar Kartikeya Dwivedi 	if (!v)
14004accf79SKumar Kartikeya Dwivedi 		return 0;
14104accf79SKumar Kartikeya Dwivedi 
14204accf79SKumar Kartikeya Dwivedi 	unref_ptr = v->unref_ptr;
14304accf79SKumar Kartikeya Dwivedi 	if (!unref_ptr)
14404accf79SKumar Kartikeya Dwivedi 		return 0;
14504accf79SKumar Kartikeya Dwivedi 	unref_ptr = (void *)unref_ptr + 4;
14604accf79SKumar Kartikeya Dwivedi 	v->unref_ptr = unref_ptr;
14704accf79SKumar Kartikeya Dwivedi 
14804accf79SKumar Kartikeya Dwivedi 	return 0;
14904accf79SKumar Kartikeya Dwivedi }
15004accf79SKumar Kartikeya Dwivedi 
15104accf79SKumar Kartikeya Dwivedi SEC("?tc")
15226c386ecSAndrii Nakryiko __failure __msg("R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_")
marked_as_untrusted_or_null(struct __sk_buff * ctx)15304accf79SKumar Kartikeya Dwivedi int marked_as_untrusted_or_null(struct __sk_buff *ctx)
15404accf79SKumar Kartikeya Dwivedi {
15504accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
15604accf79SKumar Kartikeya Dwivedi 	int key = 0;
15704accf79SKumar Kartikeya Dwivedi 
15804accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
15904accf79SKumar Kartikeya Dwivedi 	if (!v)
16004accf79SKumar Kartikeya Dwivedi 		return 0;
16104accf79SKumar Kartikeya Dwivedi 
16204accf79SKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(v->unref_ptr);
16304accf79SKumar Kartikeya Dwivedi 	return 0;
16404accf79SKumar Kartikeya Dwivedi }
16504accf79SKumar Kartikeya Dwivedi 
16604accf79SKumar Kartikeya Dwivedi SEC("?tc")
16726c386ecSAndrii Nakryiko __failure __msg("access beyond struct prog_test_ref_kfunc at off 32 size 4")
correct_btf_id_check_size(struct __sk_buff * ctx)16804accf79SKumar Kartikeya Dwivedi int correct_btf_id_check_size(struct __sk_buff *ctx)
16904accf79SKumar Kartikeya Dwivedi {
17004accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *p;
17104accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
17204accf79SKumar Kartikeya Dwivedi 	int key = 0;
17304accf79SKumar Kartikeya Dwivedi 
17404accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
17504accf79SKumar Kartikeya Dwivedi 	if (!v)
17604accf79SKumar Kartikeya Dwivedi 		return 0;
17704accf79SKumar Kartikeya Dwivedi 
17804accf79SKumar Kartikeya Dwivedi 	p = v->unref_ptr;
17904accf79SKumar Kartikeya Dwivedi 	if (!p)
18004accf79SKumar Kartikeya Dwivedi 		return 0;
18104accf79SKumar Kartikeya Dwivedi 	return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc));
18204accf79SKumar Kartikeya Dwivedi }
18304accf79SKumar Kartikeya Dwivedi 
18404accf79SKumar Kartikeya Dwivedi SEC("?tc")
18526c386ecSAndrii Nakryiko __failure __msg("R1 type=untrusted_ptr_ expected=percpu_ptr_")
inherit_untrusted_on_walk(struct __sk_buff * ctx)18604accf79SKumar Kartikeya Dwivedi int inherit_untrusted_on_walk(struct __sk_buff *ctx)
18704accf79SKumar Kartikeya Dwivedi {
18804accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *unref_ptr;
18904accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
19004accf79SKumar Kartikeya Dwivedi 	int key = 0;
19104accf79SKumar Kartikeya Dwivedi 
19204accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
19304accf79SKumar Kartikeya Dwivedi 	if (!v)
19404accf79SKumar Kartikeya Dwivedi 		return 0;
19504accf79SKumar Kartikeya Dwivedi 
19604accf79SKumar Kartikeya Dwivedi 	unref_ptr = v->unref_ptr;
19704accf79SKumar Kartikeya Dwivedi 	if (!unref_ptr)
19804accf79SKumar Kartikeya Dwivedi 		return 0;
19904accf79SKumar Kartikeya Dwivedi 	unref_ptr = unref_ptr->next;
20004accf79SKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(unref_ptr);
20104accf79SKumar Kartikeya Dwivedi 	return 0;
20204accf79SKumar Kartikeya Dwivedi }
20304accf79SKumar Kartikeya Dwivedi 
20404accf79SKumar Kartikeya Dwivedi SEC("?tc")
20526c386ecSAndrii Nakryiko __failure __msg("off=8 kptr isn't referenced kptr")
reject_kptr_xchg_on_unref(struct __sk_buff * ctx)20604accf79SKumar Kartikeya Dwivedi int reject_kptr_xchg_on_unref(struct __sk_buff *ctx)
20704accf79SKumar Kartikeya Dwivedi {
20804accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
20904accf79SKumar Kartikeya Dwivedi 	int key = 0;
21004accf79SKumar Kartikeya Dwivedi 
21104accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
21204accf79SKumar Kartikeya Dwivedi 	if (!v)
21304accf79SKumar Kartikeya Dwivedi 		return 0;
21404accf79SKumar Kartikeya Dwivedi 
21504accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg(&v->unref_ptr, NULL);
21604accf79SKumar Kartikeya Dwivedi 	return 0;
21704accf79SKumar Kartikeya Dwivedi }
21804accf79SKumar Kartikeya Dwivedi 
21904accf79SKumar Kartikeya Dwivedi SEC("?tc")
22020c09d92SAlexei Starovoitov __failure __msg("R1 type=rcu_ptr_or_null_ expected=percpu_ptr_")
mark_ref_as_untrusted_or_null(struct __sk_buff * ctx)22104accf79SKumar Kartikeya Dwivedi int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx)
22204accf79SKumar Kartikeya Dwivedi {
22304accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
22404accf79SKumar Kartikeya Dwivedi 	int key = 0;
22504accf79SKumar Kartikeya Dwivedi 
22604accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
22704accf79SKumar Kartikeya Dwivedi 	if (!v)
22804accf79SKumar Kartikeya Dwivedi 		return 0;
22904accf79SKumar Kartikeya Dwivedi 
23004accf79SKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(v->ref_ptr);
23104accf79SKumar Kartikeya Dwivedi 	return 0;
23204accf79SKumar Kartikeya Dwivedi }
23304accf79SKumar Kartikeya Dwivedi 
23404accf79SKumar Kartikeya Dwivedi SEC("?tc")
23526c386ecSAndrii Nakryiko __failure __msg("store to referenced kptr disallowed")
reject_untrusted_store_to_ref(struct __sk_buff * ctx)23604accf79SKumar Kartikeya Dwivedi int reject_untrusted_store_to_ref(struct __sk_buff *ctx)
23704accf79SKumar Kartikeya Dwivedi {
23804accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *p;
23904accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
24004accf79SKumar Kartikeya Dwivedi 	int key = 0;
24104accf79SKumar Kartikeya Dwivedi 
24204accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
24304accf79SKumar Kartikeya Dwivedi 	if (!v)
24404accf79SKumar Kartikeya Dwivedi 		return 0;
24504accf79SKumar Kartikeya Dwivedi 
24604accf79SKumar Kartikeya Dwivedi 	p = v->ref_ptr;
24704accf79SKumar Kartikeya Dwivedi 	if (!p)
24804accf79SKumar Kartikeya Dwivedi 		return 0;
24904accf79SKumar Kartikeya Dwivedi 	/* Checkmate, clang */
25004accf79SKumar Kartikeya Dwivedi 	*(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p;
25104accf79SKumar Kartikeya Dwivedi 	return 0;
25204accf79SKumar Kartikeya Dwivedi }
25304accf79SKumar Kartikeya Dwivedi 
25404accf79SKumar Kartikeya Dwivedi SEC("?tc")
25520c09d92SAlexei Starovoitov __failure __msg("R2 must be referenced")
reject_untrusted_xchg(struct __sk_buff * ctx)25604accf79SKumar Kartikeya Dwivedi int reject_untrusted_xchg(struct __sk_buff *ctx)
25704accf79SKumar Kartikeya Dwivedi {
25804accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *p;
25904accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
26004accf79SKumar Kartikeya Dwivedi 	int key = 0;
26104accf79SKumar Kartikeya Dwivedi 
26204accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
26304accf79SKumar Kartikeya Dwivedi 	if (!v)
26404accf79SKumar Kartikeya Dwivedi 		return 0;
26504accf79SKumar Kartikeya Dwivedi 
26604accf79SKumar Kartikeya Dwivedi 	p = v->ref_ptr;
26704accf79SKumar Kartikeya Dwivedi 	if (!p)
26804accf79SKumar Kartikeya Dwivedi 		return 0;
26904accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg(&v->ref_ptr, p);
27004accf79SKumar Kartikeya Dwivedi 	return 0;
27104accf79SKumar Kartikeya Dwivedi }
27204accf79SKumar Kartikeya Dwivedi 
27304accf79SKumar Kartikeya Dwivedi SEC("?tc")
27426c386ecSAndrii Nakryiko __failure
27526c386ecSAndrii Nakryiko __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member")
reject_bad_type_xchg(struct __sk_buff * ctx)27604accf79SKumar Kartikeya Dwivedi int reject_bad_type_xchg(struct __sk_buff *ctx)
27704accf79SKumar Kartikeya Dwivedi {
27804accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *ref_ptr;
27904accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
28004accf79SKumar Kartikeya Dwivedi 	int key = 0;
28104accf79SKumar Kartikeya Dwivedi 
28204accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
28304accf79SKumar Kartikeya Dwivedi 	if (!v)
28404accf79SKumar Kartikeya Dwivedi 		return 0;
28504accf79SKumar Kartikeya Dwivedi 
28604accf79SKumar Kartikeya Dwivedi 	ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
28704accf79SKumar Kartikeya Dwivedi 	if (!ref_ptr)
28804accf79SKumar Kartikeya Dwivedi 		return 0;
28904accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr);
29004accf79SKumar Kartikeya Dwivedi 	return 0;
29104accf79SKumar Kartikeya Dwivedi }
29204accf79SKumar Kartikeya Dwivedi 
29304accf79SKumar Kartikeya Dwivedi SEC("?tc")
29426c386ecSAndrii Nakryiko __failure __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc")
reject_member_of_ref_xchg(struct __sk_buff * ctx)29504accf79SKumar Kartikeya Dwivedi int reject_member_of_ref_xchg(struct __sk_buff *ctx)
29604accf79SKumar Kartikeya Dwivedi {
29704accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *ref_ptr;
29804accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
29904accf79SKumar Kartikeya Dwivedi 	int key = 0;
30004accf79SKumar Kartikeya Dwivedi 
30104accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
30204accf79SKumar Kartikeya Dwivedi 	if (!v)
30304accf79SKumar Kartikeya Dwivedi 		return 0;
30404accf79SKumar Kartikeya Dwivedi 
30504accf79SKumar Kartikeya Dwivedi 	ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
30604accf79SKumar Kartikeya Dwivedi 	if (!ref_ptr)
30704accf79SKumar Kartikeya Dwivedi 		return 0;
30804accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb);
30904accf79SKumar Kartikeya Dwivedi 	return 0;
31004accf79SKumar Kartikeya Dwivedi }
31104accf79SKumar Kartikeya Dwivedi 
31204accf79SKumar Kartikeya Dwivedi SEC("?syscall")
31326c386ecSAndrii Nakryiko __failure __msg("kptr cannot be accessed indirectly by helper")
reject_indirect_helper_access(struct __sk_buff * ctx)31404accf79SKumar Kartikeya Dwivedi int reject_indirect_helper_access(struct __sk_buff *ctx)
31504accf79SKumar Kartikeya Dwivedi {
31604accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
31704accf79SKumar Kartikeya Dwivedi 	int key = 0;
31804accf79SKumar Kartikeya Dwivedi 
31904accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
32004accf79SKumar Kartikeya Dwivedi 	if (!v)
32104accf79SKumar Kartikeya Dwivedi 		return 0;
32204accf79SKumar Kartikeya Dwivedi 
32304accf79SKumar Kartikeya Dwivedi 	bpf_get_current_comm(v, sizeof(v->buf) + 1);
32404accf79SKumar Kartikeya Dwivedi 	return 0;
32504accf79SKumar Kartikeya Dwivedi }
32604accf79SKumar Kartikeya Dwivedi 
32704accf79SKumar Kartikeya Dwivedi __noinline
write_func(int * p)32804accf79SKumar Kartikeya Dwivedi int write_func(int *p)
32904accf79SKumar Kartikeya Dwivedi {
33004accf79SKumar Kartikeya Dwivedi 	return p ? *p = 42 : 0;
33104accf79SKumar Kartikeya Dwivedi }
33204accf79SKumar Kartikeya Dwivedi 
33304accf79SKumar Kartikeya Dwivedi SEC("?tc")
33426c386ecSAndrii Nakryiko __failure __msg("kptr cannot be accessed indirectly by helper")
reject_indirect_global_func_access(struct __sk_buff * ctx)33504accf79SKumar Kartikeya Dwivedi int reject_indirect_global_func_access(struct __sk_buff *ctx)
33604accf79SKumar Kartikeya Dwivedi {
33704accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
33804accf79SKumar Kartikeya Dwivedi 	int key = 0;
33904accf79SKumar Kartikeya Dwivedi 
34004accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
34104accf79SKumar Kartikeya Dwivedi 	if (!v)
34204accf79SKumar Kartikeya Dwivedi 		return 0;
34304accf79SKumar Kartikeya Dwivedi 
34404accf79SKumar Kartikeya Dwivedi 	return write_func((void *)v + 5);
34504accf79SKumar Kartikeya Dwivedi }
34604accf79SKumar Kartikeya Dwivedi 
34704accf79SKumar Kartikeya Dwivedi SEC("?tc")
34826c386ecSAndrii Nakryiko __failure __msg("Unreleased reference id=5 alloc_insn=")
kptr_xchg_ref_state(struct __sk_buff * ctx)34904accf79SKumar Kartikeya Dwivedi int kptr_xchg_ref_state(struct __sk_buff *ctx)
35004accf79SKumar Kartikeya Dwivedi {
35104accf79SKumar Kartikeya Dwivedi 	struct prog_test_ref_kfunc *p;
35204accf79SKumar Kartikeya Dwivedi 	struct map_value *v;
35304accf79SKumar Kartikeya Dwivedi 	int key = 0;
35404accf79SKumar Kartikeya Dwivedi 
35504accf79SKumar Kartikeya Dwivedi 	v = bpf_map_lookup_elem(&array_map, &key);
35604accf79SKumar Kartikeya Dwivedi 	if (!v)
35704accf79SKumar Kartikeya Dwivedi 		return 0;
35804accf79SKumar Kartikeya Dwivedi 
35904accf79SKumar Kartikeya Dwivedi 	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
36004accf79SKumar Kartikeya Dwivedi 	if (!p)
36104accf79SKumar Kartikeya Dwivedi 		return 0;
36204accf79SKumar Kartikeya Dwivedi 	bpf_kptr_xchg(&v->ref_ptr, p);
36304accf79SKumar Kartikeya Dwivedi 	return 0;
36404accf79SKumar Kartikeya Dwivedi }
36504accf79SKumar Kartikeya Dwivedi 
36604accf79SKumar Kartikeya Dwivedi SEC("?tc")
36767efbd57SDavid Vernet __failure __msg("Possibly NULL pointer passed to helper arg2")
kptr_xchg_possibly_null(struct __sk_buff * ctx)36867efbd57SDavid Vernet int kptr_xchg_possibly_null(struct __sk_buff *ctx)
36967efbd57SDavid Vernet {
37067efbd57SDavid Vernet 	struct prog_test_ref_kfunc *p;
37167efbd57SDavid Vernet 	struct map_value *v;
37267efbd57SDavid Vernet 	int key = 0;
37367efbd57SDavid Vernet 
37467efbd57SDavid Vernet 	v = bpf_map_lookup_elem(&array_map, &key);
37567efbd57SDavid Vernet 	if (!v)
37667efbd57SDavid Vernet 		return 0;
37767efbd57SDavid Vernet 
37867efbd57SDavid Vernet 	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
37967efbd57SDavid Vernet 
38067efbd57SDavid Vernet 	/* PTR_TO_BTF_ID | PTR_MAYBE_NULL passed to bpf_kptr_xchg() */
38167efbd57SDavid Vernet 	p = bpf_kptr_xchg(&v->ref_ptr, p);
38267efbd57SDavid Vernet 	if (p)
38367efbd57SDavid Vernet 		bpf_kfunc_call_test_release(p);
38467efbd57SDavid Vernet 
38567efbd57SDavid Vernet 	return 0;
38667efbd57SDavid Vernet }
38767efbd57SDavid Vernet 
38804accf79SKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
389