diff options
| author | Ian Rogers <irogers@google.com> | 2026-07-21 16:52:52 -0700 |
|---|---|---|
| committer | Namhyung Kim <namhyung@kernel.org> | 2026-08-07 09:43:36 -0700 |
| commit | 093f58e60e9548d35c9a3c2eee7223add4d81aba (patch) | |
| tree | 7386c9aaa4f2a3e539fe4f1604e5e8cf97a7cba6 /tools/perf | |
| parent | 505a498a3757f188fe0ddd67b2d26794e8922cc5 (diff) | |
| download | linux-next-093f58e60e9548d35c9a3c2eee7223add4d81aba.tar.gz linux-next-093f58e60e9548d35c9a3c2eee7223add4d81aba.zip | |
perf synthetic-events: Fix stack buffer overflow and bounds in cgroup synthesis
Fix a pre-existing stack buffer overflow bug in
perf_event__synthesize_cgroup() where an in-place null padding loop wrote
bytes past the end of the cgrp_root stack array buffer during cgroup tree
traversal. Eliminate in-place path mutation, use PERF_ALIGN for path_len,
clamp raw_path_len to prevent sample ID header trailer overruns, and use
strlcpy with combined zero padding for alignment and sample ID headers.
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/synthetic-events.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 832b74ffb4db..05075840707c 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -635,15 +635,22 @@ static int perf_event__synthesize_cgroup(const struct perf_tool *tool, struct machine *machine) { size_t event_size = sizeof(event->cgroup) - sizeof(event->cgroup.path); - size_t path_len = strlen(path) - mount_len + 1; + size_t raw_path_len, path_len, max_path_len; struct { struct file_handle fh; uint64_t cgroup_id; } handle; int mount_id; - while (path_len % sizeof(u64)) - path[mount_len + path_len++] = '\0'; + if (strlen(path) < mount_len) + return -1; + + max_path_len = sizeof(event->cgroup.path) - machine->id_hdr_size; + raw_path_len = strlen(path) - mount_len + 1; + if (raw_path_len > max_path_len) + raw_path_len = max_path_len; + + path_len = PERF_ALIGN(raw_path_len, sizeof(u64)); memset(&event->cgroup, 0, event_size); @@ -657,9 +664,9 @@ static int perf_event__synthesize_cgroup(const struct perf_tool *tool, } event->cgroup.id = handle.cgroup_id; - strncpy(event->cgroup.path, path + mount_len, path_len); - memset((char *)event + offsetof(struct perf_record_cgroup, path) + path_len, - 0, machine->id_hdr_size); + strlcpy(event->cgroup.path, path + mount_len, raw_path_len); + memset((char *)event + offsetof(struct perf_record_cgroup, path) + raw_path_len, + 0, (path_len - raw_path_len) + machine->id_hdr_size); if (perf_tool__process_synth_event(tool, event, machine, process) < 0) { pr_debug("process synth event failed\n"); |
