Re: [PATCH v6 01/26] perf trace: Set the augmented arg header in the augmenters that omit it
From: Namhyung Kim
Date: Tue Sep 29 2026 - 23:51:02 EST
On Mon, Sep 28, 2026 at 11:25:40AM -0700, Ian Rogers wrote:
> The augmenters build records in augmented_args_tmp, a per-CPU scratch
> buffer reused by every syscall, so a header field that isn't written
> holds a stale value from an earlier syscall. sys_enter_sendto(),
> sys_enter_perf_event_open(), sys_enter_clock_nanosleep() and
> sys_enter_nanosleep() never set the struct augmented_arg size and err,
> and augment_arg() doesn't set err.
>
> Set both. When bpf_probe_read_user() fails in the connect, sendto and
> nanosleep augmenters, report a zero sized payload and the error rather
> than the stale scratch contents.
>
> Assisted-by: Antigravity:gemini-3.1-pro
> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
Reviewed-by: Namhyung Kim <namhyung@xxxxxxxxxx>
Thanks,
Namhyung
> ---
> .../bpf_skel/augmented_raw_syscalls.bpf.c | 37 ++++++++++++++++---
> 1 file changed, 31 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> index 3bc9e28a9b8a..f7c9eb49648f 100644
> --- a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> +++ b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> @@ -210,6 +210,7 @@ int sys_enter_connect(struct syscall_enter_args *args)
> const void *sockaddr_arg = (const void *)args->args[1];
> unsigned int socklen = args->args[2];
> unsigned int len = sizeof(u64) + sizeof(augmented_args->args); // the size + err in all 'augmented_arg' structs
> + int err;
>
> if (augmented_args == NULL)
> return 1; /* Failure: don't filter */
> @@ -217,9 +218,11 @@ int sys_enter_connect(struct syscall_enter_args *args)
> _Static_assert(is_power_of_2(sizeof(augmented_args->arg.saddr)), "sizeof(augmented_args->arg.saddr) needs to be a power of two");
> socklen &= sizeof(augmented_args->arg.saddr) - 1;
>
> - bpf_probe_read_user(&augmented_args->arg.saddr, socklen, sockaddr_arg);
> + err = bpf_probe_read_user(&augmented_args->arg.saddr, socklen, sockaddr_arg);
> + if (err)
> + socklen = 0;
> augmented_args->arg.size = socklen;
> - augmented_args->arg.err = 0;
> + augmented_args->arg.err = err;
>
> return augmented__output(args, augmented_args, len + socklen);
> }
> @@ -231,13 +234,18 @@ int sys_enter_sendto(struct syscall_enter_args *args)
> const void *sockaddr_arg = (const void *)args->args[4];
> unsigned int socklen = args->args[5];
> unsigned int len = sizeof(u64) + sizeof(augmented_args->args); // the size + err in all 'augmented_arg' structs
> + int err;
>
> if (augmented_args == NULL)
> return 1; /* Failure: don't filter */
>
> socklen &= sizeof(augmented_args->arg.saddr) - 1;
>
> - bpf_probe_read_user(&augmented_args->arg.saddr, socklen, sockaddr_arg);
> + err = bpf_probe_read_user(&augmented_args->arg.saddr, socklen, sockaddr_arg);
> + if (err)
> + socklen = 0;
> + augmented_args->arg.size = socklen;
> + augmented_args->arg.err = err;
>
> return augmented__output(args, augmented_args, len + socklen);
> }
> @@ -372,6 +380,9 @@ int sys_enter_perf_event_open(struct syscall_enter_args *args)
> if (bpf_probe_read_user(&augmented_args->arg.value, size, attr) < 0)
> goto failure;
>
> + augmented_args->arg.size = size;
> + augmented_args->arg.err = 0;
> +
> return augmented__output(args, augmented_args, len + size);
> failure:
> return 1; /* Failure: don't filter */
> @@ -384,6 +395,7 @@ int sys_enter_clock_nanosleep(struct syscall_enter_args *args)
> const void *rqtp_arg = (const void *)args->args[2];
> unsigned int len = sizeof(u64) + sizeof(augmented_args->args); // the size + err in all 'augmented_arg' structs
> __u32 size = sizeof(struct timespec64);
> + int err;
>
> if (augmented_args == NULL)
> goto failure;
> @@ -391,7 +403,11 @@ int sys_enter_clock_nanosleep(struct syscall_enter_args *args)
> if (size > sizeof(augmented_args->arg.value))
> goto failure;
>
> - bpf_probe_read_user(&augmented_args->arg.value, size, rqtp_arg);
> + err = bpf_probe_read_user(&augmented_args->arg.value, size, rqtp_arg);
> + if (err)
> + size = 0;
> + augmented_args->arg.size = size;
> + augmented_args->arg.err = err;
>
> return augmented__output(args, augmented_args, len + size);
> failure:
> @@ -405,6 +421,7 @@ int sys_enter_nanosleep(struct syscall_enter_args *args)
> const void *req_arg = (const void *)args->args[0];
> unsigned int len = sizeof(augmented_args->args);
> __u32 size = sizeof(struct timespec64);
> + int err;
>
> if (augmented_args == NULL)
> goto failure;
> @@ -412,7 +429,11 @@ int sys_enter_nanosleep(struct syscall_enter_args *args)
> if (size > sizeof(augmented_args->arg.value))
> goto failure;
>
> - bpf_probe_read_user(&augmented_args->arg.value, size, req_arg);
> + err = bpf_probe_read_user(&augmented_args->arg.value, size, req_arg);
> + if (err)
> + size = 0;
> + augmented_args->arg.size = size;
> + augmented_args->arg.err = err;
>
> return augmented__output(args, augmented_args, len + size);
> failure:
> @@ -445,6 +466,7 @@ static inline int augment_arg(struct syscall_enter_args *args, int i,
> struct beauty_payload_enter *payload, u64 offset)
> {
> int index, value_size = sizeof(struct augmented_arg) - offsetof(struct augmented_arg, value);
> + int read_err = 0;
> struct augmented_arg *payload_offset;
> s64 aug_size, size;
> bool augmented;
> @@ -467,8 +489,10 @@ static inline int augment_arg(struct syscall_enter_args *args, int i,
> if (size == 1) { /* string */
> aug_size = bpf_probe_read_user_str(payload_offset->value, value_size, arg);
> /* minimum of 0 to pass the verifier */
> - if (aug_size < 0)
> + if (aug_size < 0) {
> + read_err = aug_size;
> aug_size = 0;
> + }
>
> augmented = true;
> } else if (size > 0 && size <= value_size) { /* struct */
> @@ -498,6 +522,7 @@ static inline int augment_arg(struct syscall_enter_args *args, int i,
> return -1;
>
> payload_offset->size = aug_size;
> + payload_offset->err = read_err;
> return written;
> }
>
> --
> 2.56.0.rc1.315.gc6ed9934b7-goog
>