@@ -288,6 +288,10 @@ int sys_enter_rename(struct syscall_enter_args *args)
288
288
augmented_args -> arg .size = PERF_ALIGN (oldpath_len + 1 , sizeof (u64 ));
289
289
len += augmented_args -> arg .size ;
290
290
291
+ /* Every read from userspace is limited to value size */
292
+ if (augmented_args -> arg .size > sizeof (augmented_args -> arg .value ))
293
+ return 1 ; /* Failure: don't filter */
294
+
291
295
struct augmented_arg * arg2 = (void * )& augmented_args -> arg .value + augmented_args -> arg .size ;
292
296
293
297
newpath_len = augmented_arg__read_str (arg2 , newpath_arg , sizeof (augmented_args -> arg .value ));
@@ -315,6 +319,10 @@ int sys_enter_renameat2(struct syscall_enter_args *args)
315
319
augmented_args -> arg .size = PERF_ALIGN (oldpath_len + 1 , sizeof (u64 ));
316
320
len += augmented_args -> arg .size ;
317
321
322
+ /* Every read from userspace is limited to value size */
323
+ if (augmented_args -> arg .size > sizeof (augmented_args -> arg .value ))
324
+ return 1 ; /* Failure: don't filter */
325
+
318
326
struct augmented_arg * arg2 = (void * )& augmented_args -> arg .value + augmented_args -> arg .size ;
319
327
320
328
newpath_len = augmented_arg__read_str (arg2 , newpath_arg , sizeof (augmented_args -> arg .value ));
@@ -423,8 +431,9 @@ static bool pid_filter__has(struct pids_filtered *pids, pid_t pid)
423
431
static int augment_sys_enter (void * ctx , struct syscall_enter_args * args )
424
432
{
425
433
bool augmented , do_output = false;
426
- int zero = 0 , size , aug_size , index , output = 0 ,
434
+ int zero = 0 , size , aug_size , index ,
427
435
value_size = sizeof (struct augmented_arg ) - offsetof(struct augmented_arg , value );
436
+ u64 output = 0 ; /* has to be u64, otherwise it won't pass the verifier */
428
437
unsigned int nr , * beauty_map ;
429
438
struct beauty_payload_enter * payload ;
430
439
void * arg , * payload_offset ;
@@ -490,18 +499,25 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
490
499
}
491
500
}
492
501
502
+ /* Augmented data size is limited to sizeof(augmented_arg->unnamed union with value field) */
503
+ if (aug_size > value_size )
504
+ aug_size = value_size ;
505
+
493
506
/* write data to payload */
494
507
if (augmented ) {
495
508
int written = offsetof(struct augmented_arg , value ) + aug_size ;
496
509
510
+ if (written < 0 || written > sizeof (struct augmented_arg ))
511
+ return 1 ;
512
+
497
513
((struct augmented_arg * )payload_offset )-> size = aug_size ;
498
514
output += written ;
499
515
payload_offset += written ;
500
516
do_output = true;
501
517
}
502
518
}
503
519
504
- if (!do_output )
520
+ if (!do_output || ( sizeof ( struct syscall_enter_args ) + output ) > sizeof ( struct beauty_payload_enter ) )
505
521
return 1 ;
506
522
507
523
return augmented__beauty_output (ctx , payload , sizeof (struct syscall_enter_args ) + output );
0 commit comments