[PATCH 4/5] perf header: Validate bitmap size before allocating in do_read_bitmap()
From: Arnaldo Carvalho de Melo
Date: Wed Apr 15 2026 - 20:16:45 EST
From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
do_read_bitmap() reads a u64 bit count from the file and passes it
to bitmap_zalloc() without checking it against the remaining section
size. A crafted perf.data could trigger a large allocation that would
only fail later when the per-element reads exceed section bounds.
Additionally, bitmap_zalloc() takes an int parameter, so a crafted
size with bits set above bit 31 (e.g. 0x100000040) would pass the
section bounds check but truncate when passed to bitmap_zalloc(),
allocating a much smaller buffer than the subsequent read loop
expects.
Reject size values that exceed INT_MAX, and check that the data
needed (BITS_TO_U64(size) u64 values) fits in the remaining section
before allocating.
Currently used by process_mem_topology() for HEADER_MEM_TOPOLOGY.
Reported-by: sashiko-bot@xxxxxxxxxx
Link: https://lore.kernel.org/linux-perf-users/20260414224622.2AE69C19425@xxxxxxxxxxxxxxx/
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Ian Rogers <irogers@xxxxxxxxxx>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/util/header.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 3302748bac786fdf..e1fed6f1c5e2fa4b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -300,6 +300,11 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
if (ret)
return ret;
+ /* bitmap_zalloc() takes an int; reject u64 values that truncate. */
+ if (size > INT_MAX ||
+ BITS_TO_U64(size) > (ff->size - ff->offset) / sizeof(u64))
+ return -1;
+
set = bitmap_zalloc(size);
if (!set)
return -ENOMEM;
--
2.53.0