@@ -3216,24 +3216,33 @@ static __inline int output_iov_data_copy(const struct data_args_t *args,
32163216 __u32 reassembly_bytes , __u32 copy_offset )
32173217{
32183218 __u32 __len = v -> syscall_len > max_size ? max_size : v -> syscall_len ;
3219+ __u32 offset = copy_offset ;
3220+
3221+ /*
3222+ * IO event data is read from a map value buffer. The eBPF verifier
3223+ * does not allow pointer arithmetic on map_value pointers with
3224+ * unbounded offsets. IO events are not segmented, so force offset=0.
3225+ */
3226+ if (v -> source == DATA_SOURCE_IO_EVENT )
3227+ offset = 0 ;
32193228
32203229 /*
32213230 * If data reassembly is enabled, the amount of data pushed must not
32223231 * exceed the reassembly transmission limit.
32233232 */
32243233 if (reassembly_bytes > 0 )
32253234 __len = reassembly_bytes ;
3226- if (copy_offset >= __len )
3235+ if (offset >= __len )
32273236 return 0 ;
3228- __len -= copy_offset ;
3237+ __len -= offset ;
32293238
32303239 /*
32313240 * the bitwise AND operation will set the range of possible values for
32323241 * the UNKNOWN_VALUE register to [0, BUFSIZE)
32333242 */
32343243 __u32 len = __len & (sizeof (v -> data ) - 1 );
32353244
3236- len = iovecs_copy (v , v_buff , args , __len , len , copy_offset );
3245+ len = iovecs_copy (v , v_buff , args , __len , len , offset );
32373246 return len ;
32383247}
32393248
@@ -3244,16 +3253,25 @@ static __inline int output_data_copy(const struct data_args_t *args,
32443253 __u32 reassembly_bytes , char * buffer , __u32 copy_offset )
32453254{
32463255 __u32 __len = v -> syscall_len > max_size ? max_size : v -> syscall_len ;
3256+ __u32 offset = copy_offset ;
3257+
3258+ /*
3259+ * IO event data is read from a map value buffer. The eBPF verifier
3260+ * does not allow pointer arithmetic on map_value pointers with
3261+ * unbounded offsets. IO events are not segmented, so force offset=0.
3262+ */
3263+ if (v -> source == DATA_SOURCE_IO_EVENT )
3264+ offset = 0 ;
32473265
32483266 /*
32493267 * If data reassembly is enabled, the amount of data pushed must not
32503268 * exceed the reassembly transmission limit.
32513269 */
32523270 if (reassembly_bytes > 0 )
32533271 __len = reassembly_bytes ;
3254- if (copy_offset >= __len )
3272+ if (offset >= __len )
32553273 return 0 ;
3256- __len -= copy_offset ;
3274+ __len -= offset ;
32573275
32583276 /*
32593277 * the bitwise AND operation will set the range of possible values for
@@ -3262,20 +3280,20 @@ static __inline int output_data_copy(const struct data_args_t *args,
32623280 __u32 len = __len & (sizeof (v -> data ) - 1 );
32633281
32643282 if (vecs ) {
3265- len = iovecs_copy (v , v_buff , args , __len , len , copy_offset );
3283+ len = iovecs_copy (v , v_buff , args , __len , len , offset );
32663284 return len ;
32673285 }
32683286
32693287 if (__len >= sizeof (v -> data )) {
32703288 if (v -> source != DATA_SOURCE_IO_EVENT ) {
32713289 if (unlikely
32723290 (bpf_probe_read_user
3273- (v -> data , sizeof (v -> data ), buffer + copy_offset ) != 0 ))
3291+ (v -> data , sizeof (v -> data ), buffer + offset ) != 0 ))
32743292 return -1 ;
32753293 } else {
32763294 if (unlikely
32773295 (bpf_probe_read_kernel
3278- (v -> data , sizeof (v -> data ), buffer + copy_offset ) != 0 ))
3296+ (v -> data , sizeof (v -> data ), buffer ) != 0 ))
32793297 return -1 ;
32803298 }
32813299
@@ -3292,12 +3310,12 @@ static __inline int output_data_copy(const struct data_args_t *args,
32923310 */
32933311 if (v -> source != DATA_SOURCE_IO_EVENT ) {
32943312 if (unlikely (bpf_probe_read_user (v -> data ,
3295- len + 1 , buffer + copy_offset ) != 0 ))
3313+ len + 1 , buffer + offset ) != 0 ))
32963314 return -1 ;
32973315 } else {
32983316 if (unlikely (bpf_probe_read_kernel (v -> data ,
32993317 len + 1 ,
3300- buffer + copy_offset ) != 0 ))
3318+ buffer ) != 0 ))
33013319 return -1 ;
33023320 }
33033321 }
0 commit comments