Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <howardchu95@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20241011021403.4089793-3-howardchu95@gmail.com
[ Reduced the patch removing things that can be done later ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Howard Chu and committed by
Arnaldo Carvalho de Melo
395d3841 ecabac70

+18 -2
+18 -2
tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
··· 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)); ··· 318 314 oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value)); 319 315 augmented_args->arg.size = PERF_ALIGN(oldpath_len + 1, sizeof(u64)); 320 316 len += augmented_args->arg.size; 317 + 318 + /* Every read from userspace is limited to value size */ 319 + if (augmented_args->arg.size > sizeof(augmented_args->arg.value)) 320 + return 1; /* Failure: don't filter */ 321 321 322 322 struct augmented_arg *arg2 = (void *)&augmented_args->arg.value + augmented_args->arg.size; 323 323 ··· 431 423 static int augment_sys_enter(void *ctx, struct syscall_enter_args *args) 432 424 { 433 425 bool augmented, do_output = false; 434 - int zero = 0, size, aug_size, index, output = 0, 426 + int zero = 0, size, aug_size, index, 435 427 value_size = sizeof(struct augmented_arg) - offsetof(struct augmented_arg, value); 428 + u64 output = 0; /* has to be u64, otherwise it won't pass the verifier */ 436 429 unsigned int nr, *beauty_map; 437 430 struct beauty_payload_enter *payload; 438 431 void *arg, *payload_offset; ··· 499 490 } 500 491 } 501 492 493 + /* Augmented data size is limited to sizeof(augmented_arg->unnamed union with value field) */ 494 + if (aug_size > value_size) 495 + aug_size = value_size; 496 + 502 497 /* write data to payload */ 503 498 if (augmented) { 504 499 int written = offsetof(struct augmented_arg, value) + aug_size; 500 + 501 + if (written < 0 || written > sizeof(struct augmented_arg)) 502 + return 1; 505 503 506 504 ((struct augmented_arg *)payload_offset)->size = aug_size; 507 505 output += written; ··· 517 501 } 518 502 } 519 503 520 - if (!do_output) 504 + if (!do_output || (sizeof(struct syscall_enter_args) + output) > sizeof(struct beauty_payload_enter)) 521 505 return 1; 522 506 523 507 return augmented__beauty_output(ctx, payload, sizeof(struct syscall_enter_args) + output);