~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/user_ringbuf_fail.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* 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 
  8 char _license[] SEC("license") = "GPL";
  9 
 10 struct sample {
 11         int pid;
 12         int seq;
 13         long value;
 14         char comm[16];
 15 };
 16 
 17 struct {
 18         __uint(type, BPF_MAP_TYPE_USER_RINGBUF);
 19         __uint(max_entries, 4096);
 20 } user_ringbuf SEC(".maps");
 21 
 22 struct {
 23         __uint(type, BPF_MAP_TYPE_RINGBUF);
 24         __uint(max_entries, 2);
 25 } ringbuf SEC(".maps");
 26 
 27 static int map_value;
 28 
 29 static long
 30 bad_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 should
 41  * not be able to read before the pointer.
 42  */
 43 SEC("?raw_tp")
 44 __failure __msg("negative offset dynptr_ptr ptr")
 45 int 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 
 52 static long
 53 bad_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 should
 64  * not be able to read past the end of the pointer.
 65  */
 66 SEC("?raw_tp")
 67 __failure __msg("dereference of modified dynptr_ptr ptr")
 68 int 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 
 75 static long
 76 write_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 should
 84  * not be able to write to that pointer.
 85  */
 86 SEC("?raw_tp")
 87 __failure __msg("invalid mem access 'dynptr_ptr'")
 88 int 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 
 95 static long
 96 null_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 should
104  * not be able to write to that pointer.
105  */
106 SEC("?raw_tp")
107 __failure __msg("invalid mem access 'scalar'")
108 int 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 
115 static long
116 null_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 should
126  * not be able to write to that pointer.
127  */
128 SEC("?raw_tp")
129 __failure __msg("invalid mem access 'scalar'")
130 int 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 
137 static long
138 try_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 should
146  * not be able to read past the end of the pointer.
147  */
148 SEC("?raw_tp")
149 __failure __msg("cannot release unowned const bpf_dynptr")
150 int 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 
157 static long
158 try_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 should
166  * not be able to read past the end of the pointer.
167  */
168 SEC("?raw_tp")
169 __failure __msg("cannot release unowned const bpf_dynptr")
170 int 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 
177 static long
178 invalid_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 should
184  * not be able to write to that pointer.
185  */
186 SEC("?raw_tp")
187 __failure __msg("At callback return the register R0 has ")
188 int 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 
195 static long
196 try_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 
202 static long
203 try_reinit_dynptr_ringbuf(struct bpf_dynptr *dynptr, void *context)
204 {
205         bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, dynptr);
206         return 0;
207 }
208 
209 SEC("?raw_tp")
210 __failure __msg("Dynptr has to be an uninitialized dynptr")
211 int 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 
217 SEC("?raw_tp")
218 __failure __msg("Dynptr has to be an uninitialized dynptr")
219 int 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 
231 static 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 
238 SEC("?raw_tp")
239 __failure __msg("dereference of modified dynptr_ptr ptr R1 off=16384 disallowed")
240 int 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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php