cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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";