xref: /linux/tools/testing/selftests/bpf/progs/test_global_map_resize.c (revision e9ef810dfee7a2227da9d423aecb0ced35faddbe)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3 
4 #include "vmlinux.h"
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7 
8 char _license[] SEC("license") = "GPL";
9 
10 /* rodata section */
11 const volatile pid_t pid;
12 const volatile size_t bss_array_len;
13 const volatile size_t data_array_len;
14 
15 /* bss section */
16 int sum = 0;
17 int array[1];
18 
19 /* custom data section */
20 int my_array[1] SEC(".data.custom");
21 
22 /* custom data section which should NOT be resizable,
23  * since it contains a single var which is not an array
24  */
25 int my_int SEC(".data.non_array");
26 
27 /* custom data section which should NOT be resizable,
28  * since its last var is not an array
29  */
30 int my_array_first[1] SEC(".data.array_not_last");
31 int my_int_last SEC(".data.array_not_last");
32 
33 int percpu_arr[1] SEC(".data.percpu_arr");
34 
35 /* at least one extern is included, to ensure that a specific
36  * regression is tested whereby resizing resulted in a free-after-use
37  * bug after type information is invalidated by the resize operation.
38  *
39  * There isn't a particularly good API to test for this specific condition,
40  * but by having externs for the resizing tests it will cover this path.
41  */
42 extern int LINUX_KERNEL_VERSION __kconfig;
43 long version_sink;
44 
45 SEC("tp/syscalls/sys_enter_getpid")
bss_array_sum(void * ctx)46 int bss_array_sum(void *ctx)
47 {
48 	if (pid != (bpf_get_current_pid_tgid() >> 32))
49 		return 0;
50 
51 	/* this will be zero, we just rely on verifier not rejecting this */
52 	sum = percpu_arr[bpf_get_smp_processor_id()];
53 
54 	for (size_t i = 0; i < bss_array_len; ++i)
55 		sum += array[i];
56 
57 	/* see above; ensure this is not optimized out */
58 	version_sink = LINUX_KERNEL_VERSION;
59 
60 	return 0;
61 }
62 
63 SEC("tp/syscalls/sys_enter_getuid")
data_array_sum(void * ctx)64 int data_array_sum(void *ctx)
65 {
66 	if (pid != (bpf_get_current_pid_tgid() >> 32))
67 		return 0;
68 
69 	/* this will be zero, we just rely on verifier not rejecting this */
70 	sum = percpu_arr[bpf_get_smp_processor_id()];
71 
72 	for (size_t i = 0; i < data_array_len; ++i)
73 		sum += my_array[i];
74 
75 	/* see above; ensure this is not optimized out */
76 	version_sink = LINUX_KERNEL_VERSION;
77 
78 	return 0;
79 }
80 
81 SEC("struct_ops/test_1")
BPF_PROG(test_1)82 int BPF_PROG(test_1)
83 {
84 	return 0;
85 }
86 
87 struct bpf_testmod_ops {
88 	int (*test_1)(void);
89 };
90 
91 SEC(".struct_ops.link")
92 struct bpf_testmod_ops st_ops_resize = {
93 	.test_1 = (void *)test_1
94 };
95