55#include  <bpf/bpf_helpers.h> 
66#include  "bpf_misc.h" 
77#include  "bpf_experimental.h" 
8+ #include  "bpf_arena_common.h" 
89
910struct  arr_elem  {
1011	struct  bpf_res_spin_lock  lock ;
@@ -17,10 +18,29 @@ struct {
1718	__type (value , struct  arr_elem );
1819} arrmap  SEC (".maps" );
1920
21+ struct  {
22+ 	__uint (type , BPF_MAP_TYPE_ARENA );
23+ 	__uint (map_flags , BPF_F_MMAPABLE );
24+ 	__uint (max_entries , 1 ); /* number of pages */ 
25+ } arena  SEC (".maps" );
26+ 
27+ struct  elem  {
28+ 	struct  bpf_timer  timer ;
29+ };
30+ 
31+ struct  {
32+ 	__uint (type , BPF_MAP_TYPE_ARRAY );
33+ 	__uint (max_entries , 1 );
34+ 	__type (key , int );
35+ 	__type (value , struct  elem );
36+ } array  SEC (".maps" );
37+ 
2038#define  ENOSPC  28
2139#define  _STR  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2240
2341int  size ;
42+ u64  fault_addr ;
43+ void  * arena_ptr ;
2444
2545SEC ("syscall" )
2646__success  __retval (0 )
@@ -93,4 +113,125 @@ int stream_syscall(void *ctx)
93113	return  0 ;
94114}
95115
116+ SEC ("syscall" )
117+ __arch_x86_64 
118+ __arch_arm64 
119+ __success  __retval (0 )
120+ __stderr ("ERROR: Arena WRITE access at unmapped address 0x{{.*}}" )
121+ __stderr ("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}" )
122+ __stderr ("Call trace:\n" 
123+ "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 
124+ "|[ \t]+[^\n]+\n)*}}" )
125+ int  stream_arena_write_fault (void  * ctx )
126+ {
127+ 	struct  bpf_arena  * ptr  =  (void  * )& arena ;
128+ 	u64  user_vm_start ;
129+ 
130+ 	/* Prevent GCC bounds warning: casting &arena to struct bpf_arena * 
131+ 	 * triggers bounds checking since the map definition is smaller than struct 
132+ 	 * bpf_arena. barrier_var() makes the pointer opaque to GCC, preventing the 
133+ 	 * bounds analysis 
134+ 	 */ 
135+ 	barrier_var (ptr );
136+ 	user_vm_start  =  ptr -> user_vm_start ;
137+ 	fault_addr  =  user_vm_start  +  0x7fff ;
138+ 	bpf_addr_space_cast (user_vm_start , 0 , 1 );
139+ 	asm volatile  (
140+ 		"r1 = %0;" 
141+ 		"r2 = 1;" 
142+ 		"*(u32 *)(r1 + 0x7fff) = r2;" 
143+ 		:
144+ 		: "r"  (user_vm_start )
145+ 		: "r1" , "r2" 
146+ 	);
147+ 	return  0 ;
148+ }
149+ 
150+ SEC ("syscall" )
151+ __arch_x86_64 
152+ __arch_arm64 
153+ __success  __retval (0 )
154+ __stderr ("ERROR: Arena READ access at unmapped address 0x{{.*}}" )
155+ __stderr ("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}" )
156+ __stderr ("Call trace:\n" 
157+ "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 
158+ "|[ \t]+[^\n]+\n)*}}" )
159+ int  stream_arena_read_fault (void  * ctx )
160+ {
161+ 	struct  bpf_arena  * ptr  =  (void  * )& arena ;
162+ 	u64  user_vm_start ;
163+ 
164+ 	/* Prevent GCC bounds warning: casting &arena to struct bpf_arena * 
165+ 	 * triggers bounds checking since the map definition is smaller than struct 
166+ 	 * bpf_arena. barrier_var() makes the pointer opaque to GCC, preventing the 
167+ 	 * bounds analysis 
168+ 	 */ 
169+ 	barrier_var (ptr );
170+ 	user_vm_start  =  ptr -> user_vm_start ;
171+ 	fault_addr  =  user_vm_start  +  0x7fff ;
172+ 	bpf_addr_space_cast (user_vm_start , 0 , 1 );
173+ 	asm volatile  (
174+ 		"r1 = %0;" 
175+ 		"r1 = *(u32 *)(r1 + 0x7fff);" 
176+ 		:
177+ 		: "r"  (user_vm_start )
178+ 		: "r1" 
179+ 	);
180+ 	return  0 ;
181+ }
182+ 
183+ static  __noinline  void  subprog (void )
184+ {
185+ 	int  __arena  * addr  =  (int  __arena  * )0xdeadbeef ;
186+ 
187+ 	arena_ptr  =  & arena ;
188+ 	* addr  =  1 ;
189+ }
190+ 
191+ SEC ("syscall" )
192+ __arch_x86_64 
193+ __arch_arm64 
194+ __success  __retval (0 )
195+ __stderr ("ERROR: Arena WRITE access at unmapped address 0x{{.*}}" )
196+ __stderr ("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}" )
197+ __stderr ("Call trace:\n" 
198+ "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 
199+ "|[ \t]+[^\n]+\n)*}}" )
200+ int  stream_arena_subprog_fault (void  * ctx )
201+ {
202+ 	subprog ();
203+ 	return  0 ;
204+ }
205+ 
206+ static  __noinline  int  timer_cb (void  * map , int  * key , struct  bpf_timer  * timer )
207+ {
208+ 	int  __arena  * addr  =  (int  __arena  * )0xdeadbeef ;
209+ 
210+ 	arena_ptr  =  & arena ;
211+ 	* addr  =  1 ;
212+ 	return  0 ;
213+ }
214+ 
215+ SEC ("syscall" )
216+ __arch_x86_64 
217+ __arch_arm64 
218+ __success  __retval (0 )
219+ __stderr ("ERROR: Arena WRITE access at unmapped address 0x{{.*}}" )
220+ __stderr ("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}" )
221+ __stderr ("Call trace:\n" 
222+ "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 
223+ "|[ \t]+[^\n]+\n)*}}" )
224+ int  stream_arena_callback_fault (void  * ctx )
225+ {
226+ 	struct  bpf_timer  * arr_timer ;
227+ 
228+ 	arr_timer  =  bpf_map_lookup_elem (& array , & (int ){0 });
229+ 	if  (!arr_timer )
230+ 		return  0 ;
231+ 	bpf_timer_init (arr_timer , & array , 1 );
232+ 	bpf_timer_set_callback (arr_timer , timer_cb );
233+ 	bpf_timer_start (arr_timer , 0 , 0 );
234+ 	return  0 ;
235+ }
236+ 
96237char  _license [] SEC ("license" ) =  "GPL" ;
0 commit comments