Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3#include <vmlinux.h>
4#include <bpf/bpf_core_read.h>
5#include "bpf_misc.h"
6#include "../test_kmods/bpf_testmod_kfunc.h"
7
8SEC("tp_btf/sys_enter")
9__success
10__log_level(2)
11__msg("r8 = *(u64 *)(r7 +0) ; R7=ptr_nameidata(imm={{[0-9]+}}) R8=rdonly_untrusted_mem(sz=0)")
12__msg("r9 = *(u8 *)(r8 +0) ; R8=rdonly_untrusted_mem(sz=0) R9=scalar")
13int btf_id_to_ptr_mem(void *ctx)
14{
15 struct task_struct *task;
16 struct nameidata *idata;
17 u64 ret, off;
18
19 task = bpf_get_current_task_btf();
20 idata = task->nameidata;
21 off = bpf_core_field_offset(struct nameidata, pathname);
22 /*
23 * asm block to have reliable match target for __msg, equivalent of:
24 * ret = task->nameidata->pathname[0];
25 */
26 asm volatile (
27 "r7 = %[idata];"
28 "r7 += %[off];"
29 "r8 = *(u64 *)(r7 + 0);"
30 "r9 = *(u8 *)(r8 + 0);"
31 "%[ret] = r9;"
32 : [ret]"=r"(ret)
33 : [idata]"r"(idata),
34 [off]"r"(off)
35 : "r7", "r8", "r9");
36 return ret;
37}
38
39SEC("socket")
40__success
41__retval(0)
42int ldx_is_ok_bad_addr(void *ctx)
43{
44 char *p;
45
46 if (!bpf_core_enum_value_exists(enum bpf_features, BPF_FEAT_RDONLY_CAST_TO_VOID))
47 return 42;
48
49 p = bpf_rdonly_cast(0, 0);
50 return p[0x7fff];
51}
52
53SEC("socket")
54__success
55__retval(1)
56int ldx_is_ok_good_addr(void *ctx)
57{
58 int v, *p;
59
60 v = 1;
61 p = bpf_rdonly_cast(&v, 0);
62 return *p;
63}
64
65SEC("socket")
66__success
67int offset_not_tracked(void *ctx)
68{
69 int *p, i, s;
70
71 p = bpf_rdonly_cast(0, 0);
72 s = 0;
73 bpf_for(i, 0, 1000 * 1000 * 1000) {
74 p++;
75 s += *p;
76 }
77 return s;
78}
79
80SEC("socket")
81__failure
82__msg("cannot write into rdonly_untrusted_mem")
83int stx_not_ok(void *ctx)
84{
85 int v, *p;
86
87 v = 1;
88 p = bpf_rdonly_cast(&v, 0);
89 *p = 1;
90 return 0;
91}
92
93SEC("socket")
94__failure
95__msg("cannot write into rdonly_untrusted_mem")
96int atomic_not_ok(void *ctx)
97{
98 int v, *p;
99
100 v = 1;
101 p = bpf_rdonly_cast(&v, 0);
102 __sync_fetch_and_add(p, 1);
103 return 0;
104}
105
106SEC("socket")
107__failure
108__msg("cannot write into rdonly_untrusted_mem")
109int atomic_rmw_not_ok(void *ctx)
110{
111 long v, *p;
112
113 v = 1;
114 p = bpf_rdonly_cast(&v, 0);
115 return __sync_val_compare_and_swap(p, 0, 42);
116}
117
118SEC("socket")
119__failure
120__msg("invalid access to memory, mem_size=0 off=0 size=4")
121__msg("R1 min value is outside of the allowed memory range")
122int kfunc_param_not_ok(void *ctx)
123{
124 int *p;
125
126 p = bpf_rdonly_cast(0, 0);
127 bpf_kfunc_trusted_num_test(p);
128 return 0;
129}
130
131SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
132__failure
133__msg("R1 type=rdonly_untrusted_mem expected=")
134int helper_param_not_ok(void *ctx)
135{
136 char *p;
137
138 p = bpf_rdonly_cast(0, 0);
139 /*
140 * Any helper with ARG_CONST_SIZE_OR_ZERO constraint will do,
141 * the most permissive constraint
142 */
143 bpf_copy_from_user(p, 0, (void *)42);
144 return 0;
145}
146
147static __noinline u64 *get_some_addr(void)
148{
149 if (bpf_get_prandom_u32())
150 return bpf_rdonly_cast(0, bpf_core_type_id_kernel(struct sock));
151 else
152 return bpf_rdonly_cast(0, 0);
153}
154
155SEC("socket")
156__success
157__retval(0)
158int mixed_mem_type(void *ctx)
159{
160 u64 *p;
161
162 /* Try to avoid compiler hoisting load to if branches by using __noinline func. */
163 p = get_some_addr();
164 return *p;
165}
166
167__attribute__((__aligned__(8)))
168u8 global[] = {
169 0x11, 0x22, 0x33, 0x44,
170 0x55, 0x66, 0x77, 0x88,
171 0x99
172};
173
174__always_inline
175static u64 combine(void *p)
176{
177 u64 acc;
178
179 acc = 0;
180#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
181 acc |= (*(u64 *)p >> 56) << 24;
182 acc |= (*(u32 *)p >> 24) << 16;
183 acc |= (*(u16 *)p >> 8) << 8;
184 acc |= *(u8 *)p;
185#else
186 acc |= (*(u64 *)p & 0xff) << 24;
187 acc |= (*(u32 *)p & 0xff) << 16;
188 acc |= (*(u16 *)p & 0xff) << 8;
189 acc |= *(u8 *)p;
190#endif
191 return acc;
192}
193
194SEC("socket")
195__retval(0x88442211)
196int diff_size_access(void *ctx)
197{
198 return combine(bpf_rdonly_cast(&global, 0));
199}
200
201SEC("socket")
202__retval(0x99553322)
203int misaligned_access(void *ctx)
204{
205 return combine(bpf_rdonly_cast(&global, 0) + 1);
206}
207
208__weak int return_one(void)
209{
210 return 1;
211}
212
213SEC("socket")
214__success
215__retval(1)
216int null_check(void *ctx)
217{
218 int *p;
219
220 p = bpf_rdonly_cast(0, 0);
221 if (p == 0)
222 /* make this a function call to avoid compiler
223 * moving r0 assignment before check.
224 */
225 return return_one();
226 return 0;
227}
228
229char _license[] SEC("license") = "GPL";