brintos

brintos / linux-shallow public Read only

0
0
Text · 7.5 KiB · 450bb37 Raw
389 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <vmlinux.h>3#include <bpf/bpf_tracing.h>4#include <bpf/bpf_helpers.h>5#include <bpf/bpf_core_read.h>6#include "bpf_misc.h"7#include "../bpf_testmod/bpf_testmod_kfunc.h"8 9struct map_value {10	char buf[8];11	struct prog_test_ref_kfunc __kptr_untrusted *unref_ptr;12	struct prog_test_ref_kfunc __kptr *ref_ptr;13	struct prog_test_member __kptr *ref_memb_ptr;14};15 16struct array_map {17	__uint(type, BPF_MAP_TYPE_ARRAY);18	__type(key, int);19	__type(value, struct map_value);20	__uint(max_entries, 1);21} array_map SEC(".maps");22 23SEC("?tc")24__failure __msg("kptr access size must be BPF_DW")25int size_not_bpf_dw(struct __sk_buff *ctx)26{27	struct map_value *v;28	int key = 0;29 30	v = bpf_map_lookup_elem(&array_map, &key);31	if (!v)32		return 0;33 34	*(u32 *)&v->unref_ptr = 0;35	return 0;36}37 38SEC("?tc")39__failure __msg("kptr access cannot have variable offset")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")58__failure __msg("R1 doesn't have constant offset. kptr has to be")59int non_const_var_off_kptr_xchg(struct __sk_buff *ctx)60{61	struct map_value *v;62	int key = 0, id;63 64	v = bpf_map_lookup_elem(&array_map, &key);65	if (!v)66		return 0;67 68	id = ctx->protocol;69	if (id < 4 || id > 12)70		return 0;71	bpf_kptr_xchg((void *)v + id, NULL);72 73	return 0;74}75 76SEC("?tc")77__failure __msg("kptr access misaligned expected=8 off=7")78int misaligned_access_write(struct __sk_buff *ctx)79{80	struct map_value *v;81	int key = 0;82 83	v = bpf_map_lookup_elem(&array_map, &key);84	if (!v)85		return 0;86 87	*(void **)((void *)v + 7) = NULL;88 89	return 0;90}91 92SEC("?tc")93__failure __msg("kptr access misaligned expected=8 off=1")94int misaligned_access_read(struct __sk_buff *ctx)95{96	struct map_value *v;97	int key = 0;98 99	v = bpf_map_lookup_elem(&array_map, &key);100	if (!v)101		return 0;102 103	return *(u64 *)((void *)v + 1);104}105 106SEC("?tc")107__failure __msg("variable untrusted_ptr_ access var_off=(0x0; 0x1e0)")108int reject_var_off_store(struct __sk_buff *ctx)109{110	struct prog_test_ref_kfunc *unref_ptr;111	struct map_value *v;112	int key = 0, id;113 114	v = bpf_map_lookup_elem(&array_map, &key);115	if (!v)116		return 0;117 118	unref_ptr = v->unref_ptr;119	if (!unref_ptr)120		return 0;121	id = ctx->protocol;122	if (id < 4 || id > 12)123		return 0;124	unref_ptr += id;125	v->unref_ptr = unref_ptr;126 127	return 0;128}129 130SEC("?tc")131__failure __msg("invalid kptr access, R1 type=untrusted_ptr_prog_test_ref_kfunc")132int reject_bad_type_match(struct __sk_buff *ctx)133{134	struct prog_test_ref_kfunc *unref_ptr;135	struct map_value *v;136	int key = 0;137 138	v = bpf_map_lookup_elem(&array_map, &key);139	if (!v)140		return 0;141 142	unref_ptr = v->unref_ptr;143	if (!unref_ptr)144		return 0;145	unref_ptr = (void *)unref_ptr + 4;146	v->unref_ptr = unref_ptr;147 148	return 0;149}150 151SEC("?tc")152__failure __msg("R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_")153int marked_as_untrusted_or_null(struct __sk_buff *ctx)154{155	struct map_value *v;156	int key = 0;157 158	v = bpf_map_lookup_elem(&array_map, &key);159	if (!v)160		return 0;161 162	bpf_this_cpu_ptr(v->unref_ptr);163	return 0;164}165 166SEC("?tc")167__failure __msg("access beyond struct prog_test_ref_kfunc at off 32 size 4")168int correct_btf_id_check_size(struct __sk_buff *ctx)169{170	struct prog_test_ref_kfunc *p;171	struct map_value *v;172	int key = 0;173 174	v = bpf_map_lookup_elem(&array_map, &key);175	if (!v)176		return 0;177 178	p = v->unref_ptr;179	if (!p)180		return 0;181	return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc));182}183 184SEC("?tc")185__failure __msg("R1 type=untrusted_ptr_ expected=percpu_ptr_")186int inherit_untrusted_on_walk(struct __sk_buff *ctx)187{188	struct prog_test_ref_kfunc *unref_ptr;189	struct map_value *v;190	int key = 0;191 192	v = bpf_map_lookup_elem(&array_map, &key);193	if (!v)194		return 0;195 196	unref_ptr = v->unref_ptr;197	if (!unref_ptr)198		return 0;199	unref_ptr = unref_ptr->next;200	bpf_this_cpu_ptr(unref_ptr);201	return 0;202}203 204SEC("?tc")205__failure __msg("off=8 kptr isn't referenced kptr")206int reject_kptr_xchg_on_unref(struct __sk_buff *ctx)207{208	struct map_value *v;209	int key = 0;210 211	v = bpf_map_lookup_elem(&array_map, &key);212	if (!v)213		return 0;214 215	bpf_kptr_xchg(&v->unref_ptr, NULL);216	return 0;217}218 219SEC("?tc")220__failure __msg("R1 type=rcu_ptr_or_null_ expected=percpu_ptr_")221int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx)222{223	struct map_value *v;224	int key = 0;225 226	v = bpf_map_lookup_elem(&array_map, &key);227	if (!v)228		return 0;229 230	bpf_this_cpu_ptr(v->ref_ptr);231	return 0;232}233 234SEC("?tc")235__failure __msg("store to referenced kptr disallowed")236int reject_untrusted_store_to_ref(struct __sk_buff *ctx)237{238	struct prog_test_ref_kfunc *p;239	struct map_value *v;240	int key = 0;241 242	v = bpf_map_lookup_elem(&array_map, &key);243	if (!v)244		return 0;245 246	p = v->ref_ptr;247	if (!p)248		return 0;249	/* Checkmate, clang */250	*(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p;251	return 0;252}253 254SEC("?tc")255__failure __msg("R2 must be referenced")256int reject_untrusted_xchg(struct __sk_buff *ctx)257{258	struct prog_test_ref_kfunc *p;259	struct map_value *v;260	int key = 0;261 262	v = bpf_map_lookup_elem(&array_map, &key);263	if (!v)264		return 0;265 266	p = v->ref_ptr;267	if (!p)268		return 0;269	bpf_kptr_xchg(&v->ref_ptr, p);270	return 0;271}272 273SEC("?tc")274__failure275__msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member")276int reject_bad_type_xchg(struct __sk_buff *ctx)277{278	struct prog_test_ref_kfunc *ref_ptr;279	struct map_value *v;280	int key = 0;281 282	v = bpf_map_lookup_elem(&array_map, &key);283	if (!v)284		return 0;285 286	ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});287	if (!ref_ptr)288		return 0;289	bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr);290	return 0;291}292 293SEC("?tc")294__failure __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc")295int reject_member_of_ref_xchg(struct __sk_buff *ctx)296{297	struct prog_test_ref_kfunc *ref_ptr;298	struct map_value *v;299	int key = 0;300 301	v = bpf_map_lookup_elem(&array_map, &key);302	if (!v)303		return 0;304 305	ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});306	if (!ref_ptr)307		return 0;308	bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb);309	return 0;310}311 312SEC("?syscall")313__failure __msg("kptr cannot be accessed indirectly by helper")314int reject_indirect_helper_access(struct __sk_buff *ctx)315{316	struct map_value *v;317	int key = 0;318 319	v = bpf_map_lookup_elem(&array_map, &key);320	if (!v)321		return 0;322 323	bpf_get_current_comm(v, sizeof(v->buf) + 1);324	return 0;325}326 327__noinline328int write_func(int *p)329{330	return p ? *p = 42 : 0;331}332 333SEC("?tc")334__failure __msg("kptr cannot be accessed indirectly by helper")335int reject_indirect_global_func_access(struct __sk_buff *ctx)336{337	struct map_value *v;338	int key = 0;339 340	v = bpf_map_lookup_elem(&array_map, &key);341	if (!v)342		return 0;343 344	return write_func((void *)v + 5);345}346 347SEC("?tc")348__failure __msg("Unreleased reference id=5 alloc_insn=")349int kptr_xchg_ref_state(struct __sk_buff *ctx)350{351	struct prog_test_ref_kfunc *p;352	struct map_value *v;353	int key = 0;354 355	v = bpf_map_lookup_elem(&array_map, &key);356	if (!v)357		return 0;358 359	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});360	if (!p)361		return 0;362	bpf_kptr_xchg(&v->ref_ptr, p);363	return 0;364}365 366SEC("?tc")367__failure __msg("Possibly NULL pointer passed to helper arg2")368int kptr_xchg_possibly_null(struct __sk_buff *ctx)369{370	struct prog_test_ref_kfunc *p;371	struct map_value *v;372	int key = 0;373 374	v = bpf_map_lookup_elem(&array_map, &key);375	if (!v)376		return 0;377 378	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});379 380	/* PTR_TO_BTF_ID | PTR_MAYBE_NULL passed to bpf_kptr_xchg() */381	p = bpf_kptr_xchg(&v->ref_ptr, p);382	if (p)383		bpf_kfunc_call_test_release(p);384 385	return 0;386}387 388char _license[] SEC("license") = "GPL";389