brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · 54de038 Raw
246 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8char _license[] SEC("license") = "GPL";9 10struct sample {11	int pid;12	int seq;13	long value;14	char comm[16];15};16 17struct {18	__uint(type, BPF_MAP_TYPE_USER_RINGBUF);19	__uint(max_entries, 4096);20} user_ringbuf SEC(".maps");21 22struct {23	__uint(type, BPF_MAP_TYPE_RINGBUF);24	__uint(max_entries, 2);25} ringbuf SEC(".maps");26 27static int map_value;28 29static long30bad_access1(struct bpf_dynptr *dynptr, void *context)31{32	const struct sample *sample;33 34	sample = bpf_dynptr_data(dynptr - 1, 0, sizeof(*sample));35	bpf_printk("Was able to pass bad pointer %lx\n", (__u64)dynptr - 1);36 37	return 0;38}39 40/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should41 * not be able to read before the pointer.42 */43SEC("?raw_tp")44__failure __msg("negative offset dynptr_ptr ptr")45int user_ringbuf_callback_bad_access1(void *ctx)46{47	bpf_user_ringbuf_drain(&user_ringbuf, bad_access1, NULL, 0);48 49	return 0;50}51 52static long53bad_access2(struct bpf_dynptr *dynptr, void *context)54{55	const struct sample *sample;56 57	sample = bpf_dynptr_data(dynptr + 1, 0, sizeof(*sample));58	bpf_printk("Was able to pass bad pointer %lx\n", (__u64)dynptr + 1);59 60	return 0;61}62 63/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should64 * not be able to read past the end of the pointer.65 */66SEC("?raw_tp")67__failure __msg("dereference of modified dynptr_ptr ptr")68int user_ringbuf_callback_bad_access2(void *ctx)69{70	bpf_user_ringbuf_drain(&user_ringbuf, bad_access2, NULL, 0);71 72	return 0;73}74 75static long76write_forbidden(struct bpf_dynptr *dynptr, void *context)77{78	*((long *)dynptr) = 0;79 80	return 0;81}82 83/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should84 * not be able to write to that pointer.85 */86SEC("?raw_tp")87__failure __msg("invalid mem access 'dynptr_ptr'")88int user_ringbuf_callback_write_forbidden(void *ctx)89{90	bpf_user_ringbuf_drain(&user_ringbuf, write_forbidden, NULL, 0);91 92	return 0;93}94 95static long96null_context_write(struct bpf_dynptr *dynptr, void *context)97{98	*((__u64 *)context) = 0;99 100	return 0;101}102 103/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should104 * not be able to write to that pointer.105 */106SEC("?raw_tp")107__failure __msg("invalid mem access 'scalar'")108int user_ringbuf_callback_null_context_write(void *ctx)109{110	bpf_user_ringbuf_drain(&user_ringbuf, null_context_write, NULL, 0);111 112	return 0;113}114 115static long116null_context_read(struct bpf_dynptr *dynptr, void *context)117{118	__u64 id = *((__u64 *)context);119 120	bpf_printk("Read id %lu\n", id);121 122	return 0;123}124 125/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should126 * not be able to write to that pointer.127 */128SEC("?raw_tp")129__failure __msg("invalid mem access 'scalar'")130int user_ringbuf_callback_null_context_read(void *ctx)131{132	bpf_user_ringbuf_drain(&user_ringbuf, null_context_read, NULL, 0);133 134	return 0;135}136 137static long138try_discard_dynptr(struct bpf_dynptr *dynptr, void *context)139{140	bpf_ringbuf_discard_dynptr(dynptr, 0);141 142	return 0;143}144 145/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should146 * not be able to read past the end of the pointer.147 */148SEC("?raw_tp")149__failure __msg("cannot release unowned const bpf_dynptr")150int user_ringbuf_callback_discard_dynptr(void *ctx)151{152	bpf_user_ringbuf_drain(&user_ringbuf, try_discard_dynptr, NULL, 0);153 154	return 0;155}156 157static long158try_submit_dynptr(struct bpf_dynptr *dynptr, void *context)159{160	bpf_ringbuf_submit_dynptr(dynptr, 0);161 162	return 0;163}164 165/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should166 * not be able to read past the end of the pointer.167 */168SEC("?raw_tp")169__failure __msg("cannot release unowned const bpf_dynptr")170int user_ringbuf_callback_submit_dynptr(void *ctx)171{172	bpf_user_ringbuf_drain(&user_ringbuf, try_submit_dynptr, NULL, 0);173 174	return 0;175}176 177static long178invalid_drain_callback_return(struct bpf_dynptr *dynptr, void *context)179{180	return 2;181}182 183/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should184 * not be able to write to that pointer.185 */186SEC("?raw_tp")187__failure __msg("At callback return the register R0 has ")188int user_ringbuf_callback_invalid_return(void *ctx)189{190	bpf_user_ringbuf_drain(&user_ringbuf, invalid_drain_callback_return, NULL, 0);191 192	return 0;193}194 195static long196try_reinit_dynptr_mem(struct bpf_dynptr *dynptr, void *context)197{198	bpf_dynptr_from_mem(&map_value, 4, 0, dynptr);199	return 0;200}201 202static long203try_reinit_dynptr_ringbuf(struct bpf_dynptr *dynptr, void *context)204{205	bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, dynptr);206	return 0;207}208 209SEC("?raw_tp")210__failure __msg("Dynptr has to be an uninitialized dynptr")211int user_ringbuf_callback_reinit_dynptr_mem(void *ctx)212{213	bpf_user_ringbuf_drain(&user_ringbuf, try_reinit_dynptr_mem, NULL, 0);214	return 0;215}216 217SEC("?raw_tp")218__failure __msg("Dynptr has to be an uninitialized dynptr")219int user_ringbuf_callback_reinit_dynptr_ringbuf(void *ctx)220{221	bpf_user_ringbuf_drain(&user_ringbuf, try_reinit_dynptr_ringbuf, NULL, 0);222	return 0;223}224 225__noinline long global_call_bpf_dynptr_data(struct bpf_dynptr *dynptr)226{227	bpf_dynptr_data(dynptr, 0xA, 0xA);228	return 0;229}230 231static long callback_adjust_bpf_dynptr_reg_off(struct bpf_dynptr *dynptr,232					       void *ctx)233{234	global_call_bpf_dynptr_data(dynptr += 1024);235	return 0;236}237 238SEC("?raw_tp")239__failure __msg("dereference of modified dynptr_ptr ptr R1 off=16384 disallowed")240int user_ringbuf_callback_const_ptr_to_dynptr_reg_off(void *ctx)241{242	bpf_user_ringbuf_drain(&user_ringbuf,243			       callback_adjust_bpf_dynptr_reg_off, NULL, 0);244	return 0;245}246