Skip to content

Commit 395d384

Browse files
Sbermacmel
authored andcommitted
perf trace augmented_raw_syscalls: Add more checks to pass the verifier
Add some more checks to pass the verifier in more kernels. Signed-off-by: Howard Chu <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alan Maguire <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Reduced the patch removing things that can be done later ] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent ecabac7 commit 395d384

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ int sys_enter_rename(struct syscall_enter_args *args)
288288
augmented_args->arg.size = PERF_ALIGN(oldpath_len + 1, sizeof(u64));
289289
len += augmented_args->arg.size;
290290

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+
291295
struct augmented_arg *arg2 = (void *)&augmented_args->arg.value + augmented_args->arg.size;
292296

293297
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)
315319
augmented_args->arg.size = PERF_ALIGN(oldpath_len + 1, sizeof(u64));
316320
len += augmented_args->arg.size;
317321

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+
318326
struct augmented_arg *arg2 = (void *)&augmented_args->arg.value + augmented_args->arg.size;
319327

320328
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)
423431
static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
424432
{
425433
bool augmented, do_output = false;
426-
int zero = 0, size, aug_size, index, output = 0,
434+
int zero = 0, size, aug_size, index,
427435
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 */
428437
unsigned int nr, *beauty_map;
429438
struct beauty_payload_enter *payload;
430439
void *arg, *payload_offset;
@@ -490,18 +499,25 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
490499
}
491500
}
492501

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+
493506
/* write data to payload */
494507
if (augmented) {
495508
int written = offsetof(struct augmented_arg, value) + aug_size;
496509

510+
if (written < 0 || written > sizeof(struct augmented_arg))
511+
return 1;
512+
497513
((struct augmented_arg *)payload_offset)->size = aug_size;
498514
output += written;
499515
payload_offset += written;
500516
do_output = true;
501517
}
502518
}
503519

504-
if (!do_output)
520+
if (!do_output || (sizeof(struct syscall_enter_args) + output) > sizeof(struct beauty_payload_enter))
505521
return 1;
506522

507523
return augmented__beauty_output(ctx, payload, sizeof(struct syscall_enter_args) + output);

0 commit comments

Comments
 (0)