[PATCH v5 4/4] perf synthetic-events: Fix bounds and union member access in mmap2 build_id synthesis

From: Ian Rogers

Date: Tue Jul 21 2026 - 17:12:46 EST


Modify bounds and union member access in mmap2 build_id synthesis. Bound
max_filename_len against the minimum of filename array capacity and the
outer union stack layout minus sample ID trailers. This prevents both
-E2BIG overruns and _FORTIFY_SOURCE array bounds aborts on strlcpy even
if the enclosing union expands.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/util/synthetic-events.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index 4043d17a6140..704760e1dd5d 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -2450,13 +2450,18 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,
size_t filename_len = strlen(filename);
size_t ev_len;
u64 sample_type = sample->evsel ? sample->evsel->core.attr.sample_type : 0;
- void *array;
+ void *array = &ev;
int ret;
+ size_t max_filename_len;

- if (filename_len >= sizeof(ev.mmap2.filename))
- return -EINVAL;
+ max_filename_len = min(sizeof(ev.mmap2.filename) - 1,
+ sizeof(ev) - (MAX_ID_HDR_ENTRIES * sizeof(__u64)) -
+ offsetof(struct perf_record_mmap2, filename) - 1);

- ev_len = sizeof(ev.mmap2) - sizeof(ev.mmap2.filename) + filename_len + 1;
+ if (filename_len > max_filename_len)
+ filename_len = max_filename_len;
+
+ ev_len = offsetof(struct perf_record_mmap2, filename) + filename_len + 1;
ev_len = PERF_ALIGN(ev_len, sizeof(u64));

if (ev_len + MAX_ID_HDR_ENTRIES * sizeof(__u64) > sizeof(ev))
@@ -2476,16 +2481,15 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,

ev.mmap2.build_id_size = bid->size;
if (ev.mmap2.build_id_size > sizeof(ev.mmap2.build_id))
- ev.build_id.size = sizeof(ev.mmap2.build_id);
+ ev.mmap2.build_id_size = sizeof(ev.mmap2.build_id);
memcpy(ev.mmap2.build_id, bid->data, ev.mmap2.build_id_size);

ev.mmap2.prot = prot;
ev.mmap2.flags = flags;

- memcpy(ev.mmap2.filename, filename, min(strlen(filename), sizeof(ev.mmap.filename)));
+ strlcpy(ev.mmap2.filename, filename, filename_len + 1);

- array = &ev;
- array += ev.header.size;
+ array = (void *)((char *)&ev + ev.header.size);
ret = perf_event__synthesize_id_sample(array, sample_type, sample);
if (ret < 0)
return ret;
--
2.55.0.229.g6434b31f56-goog