xref: /linux/tools/testing/selftests/bpf/progs/verifier_btf_flex_array.c (revision f77d21245710690f3fb02d19d8dd4dc17ee58c2c)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <vmlinux.h>
4 #include <bpf/bpf_helpers.h>
5 
6 #include "bpf_experimental.h"
7 #include "bpf_misc.h"
8 
9 struct test_empty_event {};
10 
11 struct test_flex_batch {
12 	int nr;
13 	struct test_empty_event events[];
14 };
15 
16 struct map_value {
17 	struct test_flex_batch __kptr *batch;
18 };
19 
20 struct {
21 	__uint(type, BPF_MAP_TYPE_ARRAY);
22 	__type(key, int);
23 	__type(value, struct map_value);
24 	__uint(max_entries, 1);
25 } batches SEC(".maps");
26 
27 SEC("syscall")
28 __description("btf walk into flexible array of zero-sized elements")
29 __failure __msg("access beyond struct test_flex_batch at off 4 size 1")
30 int stash_and_peek(void *ctx)
31 {
32 	struct test_flex_batch *b, *old;
33 	struct map_value *v;
34 	int key = 0;
35 
36 	v = bpf_map_lookup_elem(&batches, &key);
37 	if (!v)
38 		return 0;
39 
40 	b = bpf_obj_new(struct test_flex_batch);
41 	if (!b)
42 		return 0;
43 	b->nr = 1;
44 
45 	old = bpf_kptr_xchg(&v->batch, b);
46 	if (old)
47 		bpf_obj_drop(old);
48 
49 	b = v->batch;
50 	if (!b)
51 		return 0;
52 
53 	return b->nr + *(char *)&b->events[0];
54 }
55 
56 char _license[] SEC("license") = "GPL";
57