[PATCH v2 perf-tools-next 4/6] perf trace beauty: Validate payload size in augmented timespec beautifier
From: Aaron Tomlin
Date: Sun Sep 06 2026 - 21:54:34 EST
When pretty-printing augmented timespec arguments via
syscall_arg__scnprintf_augmented_timespec(), arg->augmented.args->value
is cast to struct timespec without verifying that the captured payload
is large enough to hold the structure.
If a malformed or truncated perf.data record provides an augmented
payload smaller than sizeof(struct timespec), accessing ts->tv_sec or
ts->tv_nsec reads memory past the end of the available buffer.
Validate that arg->augmented.size is at least sizeof(struct augmented_arg)
and that augmented_arg->size is at least sizeof(struct timespec) while
remaining within the available buffer. If validation fails, fall back to
printing the raw pointer value.
Fixes: 6ac73820993c ("perf trace: Add augmenter for clock_gettime's rqtp timespec arg")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxxx>
---
tools/perf/trace/beauty/timespec.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/tools/perf/trace/beauty/timespec.c b/tools/perf/trace/beauty/timespec.c
index b14ab72a2738..fad503bd953a 100644
--- a/tools/perf/trace/beauty/timespec.c
+++ b/tools/perf/trace/beauty/timespec.c
@@ -7,15 +7,28 @@
static size_t syscall_arg__scnprintf_augmented_timespec(struct syscall_arg *arg, char *bf, size_t size)
{
- struct timespec *ts = (struct timespec *)arg->augmented.args->value;
+ struct augmented_arg *augmented_arg = arg->augmented.args;
+ struct timespec *ts;
+ if (arg->augmented.size < (int)sizeof(*augmented_arg))
+ return 0;
+
+ if (augmented_arg->size < (int)sizeof(*ts) ||
+ augmented_arg->size > arg->augmented.size - (int)sizeof(*augmented_arg))
+ return 0;
+
+ ts = (struct timespec *)augmented_arg->value;
return scnprintf(bf, size, "{ .tv_sec: %" PRIu64 ", .tv_nsec: %" PRIu64 " }", ts->tv_sec, ts->tv_nsec);
}
size_t syscall_arg__scnprintf_timespec(char *bf, size_t size, struct syscall_arg *arg)
{
- if (arg->augmented.args)
- return syscall_arg__scnprintf_augmented_timespec(arg, bf, size);
+ if (arg->augmented.args) {
+ size_t printed = syscall_arg__scnprintf_augmented_timespec(arg, bf, size);
+
+ if (printed)
+ return printed;
+ }
return scnprintf(bf, size, "%#lx", arg->val);
}
--
2.55.0