brintos

brintos / linux-shallow public Read only

0
0
Text · 6.4 KiB · 9cceb65 Raw
350 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 7#include "bpf_misc.h"8#include "bpf_experimental.h"9 10extern void bpf_rcu_read_lock(void) __ksym;11 12#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))13 14struct foo {15	struct bpf_rb_node node;16};17 18struct hmap_elem {19	struct bpf_timer timer;20};21 22struct {23	__uint(type, BPF_MAP_TYPE_HASH);24	__uint(max_entries, 64);25	__type(key, int);26	__type(value, struct hmap_elem);27} hmap SEC(".maps");28 29private(A) struct bpf_spin_lock lock;30private(A) struct bpf_rb_root rbtree __contains(foo, node);31 32__noinline void *exception_cb_bad_ret_type(u64 cookie)33{34	return NULL;35}36 37__noinline int exception_cb_bad_arg_0(void)38{39	return 0;40}41 42__noinline int exception_cb_bad_arg_2(int a, int b)43{44	return 0;45}46 47__noinline int exception_cb_ok_arg_small(int a)48{49	return 0;50}51 52SEC("?tc")53__exception_cb(exception_cb_bad_ret_type)54__failure __msg("Global function exception_cb_bad_ret_type() doesn't return scalar.")55int reject_exception_cb_type_1(struct __sk_buff *ctx)56{57	bpf_throw(0);58	return 0;59}60 61SEC("?tc")62__exception_cb(exception_cb_bad_arg_0)63__failure __msg("exception cb only supports single integer argument")64int reject_exception_cb_type_2(struct __sk_buff *ctx)65{66	bpf_throw(0);67	return 0;68}69 70SEC("?tc")71__exception_cb(exception_cb_bad_arg_2)72__failure __msg("exception cb only supports single integer argument")73int reject_exception_cb_type_3(struct __sk_buff *ctx)74{75	bpf_throw(0);76	return 0;77}78 79SEC("?tc")80__exception_cb(exception_cb_ok_arg_small)81__success82int reject_exception_cb_type_4(struct __sk_buff *ctx)83{84	bpf_throw(0);85	return 0;86}87 88__noinline89static int timer_cb(void *map, int *key, struct bpf_timer *timer)90{91	bpf_throw(0);92	return 0;93}94 95SEC("?tc")96__failure __msg("cannot be called from callback subprog")97int reject_async_callback_throw(struct __sk_buff *ctx)98{99	struct hmap_elem *elem;100 101	elem = bpf_map_lookup_elem(&hmap, &(int){0});102	if (!elem)103		return 0;104	return bpf_timer_set_callback(&elem->timer, timer_cb);105}106 107__noinline static int subprog_lock(struct __sk_buff *ctx)108{109	volatile int ret = 0;110 111	bpf_spin_lock(&lock);112	if (ctx->len)113		bpf_throw(0);114	return ret;115}116 117SEC("?tc")118__failure __msg("function calls are not allowed while holding a lock")119int reject_with_lock(void *ctx)120{121	bpf_spin_lock(&lock);122	bpf_throw(0);123	return 0;124}125 126SEC("?tc")127__failure __msg("function calls are not allowed while holding a lock")128int reject_subprog_with_lock(void *ctx)129{130	return subprog_lock(ctx);131}132 133SEC("?tc")134__failure __msg("bpf_rcu_read_unlock is missing")135int reject_with_rcu_read_lock(void *ctx)136{137	bpf_rcu_read_lock();138	bpf_throw(0);139	return 0;140}141 142__noinline static int throwing_subprog(struct __sk_buff *ctx)143{144	if (ctx->len)145		bpf_throw(0);146	return 0;147}148 149SEC("?tc")150__failure __msg("bpf_rcu_read_unlock is missing")151int reject_subprog_with_rcu_read_lock(void *ctx)152{153	bpf_rcu_read_lock();154	return throwing_subprog(ctx);155}156 157static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2)158{159	bpf_throw(0);160	return true;161}162 163SEC("?tc")164__failure __msg("function calls are not allowed while holding a lock")165int reject_with_rbtree_add_throw(void *ctx)166{167	struct foo *f;168 169	f = bpf_obj_new(typeof(*f));170	if (!f)171		return 0;172	bpf_spin_lock(&lock);173	bpf_rbtree_add(&rbtree, &f->node, rbless);174	bpf_spin_unlock(&lock);175	return 0;176}177 178SEC("?tc")179__failure __msg("Unreleased reference")180int reject_with_reference(void *ctx)181{182	struct foo *f;183 184	f = bpf_obj_new(typeof(*f));185	if (!f)186		return 0;187	bpf_throw(0);188	return 0;189}190 191__noinline static int subprog_ref(struct __sk_buff *ctx)192{193	struct foo *f;194 195	f = bpf_obj_new(typeof(*f));196	if (!f)197		return 0;198	bpf_throw(0);199	return 0;200}201 202__noinline static int subprog_cb_ref(u32 i, void *ctx)203{204	bpf_throw(0);205	return 0;206}207 208SEC("?tc")209__failure __msg("Unreleased reference")210int reject_with_cb_reference(void *ctx)211{212	struct foo *f;213 214	f = bpf_obj_new(typeof(*f));215	if (!f)216		return 0;217	bpf_loop(5, subprog_cb_ref, NULL, 0);218	bpf_obj_drop(f);219	return 0;220}221 222SEC("?tc")223__failure __msg("cannot be called from callback")224int reject_with_cb(void *ctx)225{226	bpf_loop(5, subprog_cb_ref, NULL, 0);227	return 0;228}229 230SEC("?tc")231__failure __msg("Unreleased reference")232int reject_with_subprog_reference(void *ctx)233{234	return subprog_ref(ctx) + 1;235}236 237__noinline int throwing_exception_cb(u64 c)238{239	bpf_throw(0);240	return c;241}242 243__noinline int exception_cb1(u64 c)244{245	return c;246}247 248__noinline int exception_cb2(u64 c)249{250	return c;251}252 253static __noinline int static_func(struct __sk_buff *ctx)254{255	return exception_cb1(ctx->tstamp);256}257 258__noinline int global_func(struct __sk_buff *ctx)259{260	return exception_cb1(ctx->tstamp);261}262 263SEC("?tc")264__exception_cb(throwing_exception_cb)265__failure __msg("cannot be called from callback subprog")266int reject_throwing_exception_cb(struct __sk_buff *ctx)267{268	return 0;269}270 271SEC("?tc")272__exception_cb(exception_cb1)273__failure __msg("cannot call exception cb directly")274int reject_exception_cb_call_global_func(struct __sk_buff *ctx)275{276	return global_func(ctx);277}278 279SEC("?tc")280__exception_cb(exception_cb1)281__failure __msg("cannot call exception cb directly")282int reject_exception_cb_call_static_func(struct __sk_buff *ctx)283{284	return static_func(ctx);285}286 287SEC("?tc")288__exception_cb(exception_cb1)289__exception_cb(exception_cb2)290__failure __msg("multiple exception callback tags for main subprog")291int reject_multiple_exception_cb(struct __sk_buff *ctx)292{293	bpf_throw(0);294	return 16;295}296 297__noinline int exception_cb_bad_ret(u64 c)298{299	return c;300}301 302SEC("?fentry/bpf_check")303__exception_cb(exception_cb_bad_ret)304__failure __msg("At program exit the register R0 has unknown scalar value should")305int reject_set_exception_cb_bad_ret1(void *ctx)306{307	return 0;308}309 310SEC("?fentry/bpf_check")311__failure __msg("At program exit the register R1 has smin=64 smax=64 should")312int reject_set_exception_cb_bad_ret2(void *ctx)313{314	bpf_throw(64);315	return 0;316}317 318__noinline static int loop_cb1(u32 index, int *ctx)319{320	bpf_throw(0);321	return 0;322}323 324__noinline static int loop_cb2(u32 index, int *ctx)325{326	bpf_throw(0);327	return 0;328}329 330SEC("?tc")331__failure __msg("cannot be called from callback")332int reject_exception_throw_cb(struct __sk_buff *ctx)333{334	bpf_loop(5, loop_cb1, NULL, 0);335	return 0;336}337 338SEC("?tc")339__failure __msg("cannot be called from callback")340int reject_exception_throw_cb_diff(struct __sk_buff *ctx)341{342	if (ctx->protocol)343		bpf_loop(5, loop_cb1, NULL, 0);344	else345		bpf_loop(5, loop_cb2, NULL, 0);346	return 0;347}348 349char _license[] SEC("license") = "GPL";350