* [PATCHES 0/4] More perf.data header validation
@ 2026-04-14 20:48 Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 1/4] perf header: Add section bounds checking to the fd read path Arnaldo Carvalho de Melo
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-04-14 20:48 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo
Hi,
This is picking up from what was reported in the previous
series, pre-existing lack of perf.data file validation, processing files
and buffers in header.c in a similar fashion.
There is more to process in the trace data, but that is a
different can of worms that needs to be dealt with in a similar,
upcoming patch series,
This is probably 7.2 material, but if feeling this can still
sneak into 7.1, feel free to do it :-)
Now lets see what Sashiko discovers while I still don't have it
running locally right after Claude, before submitting it publicly, which
will soon happen :-)
- Arnaldo
Arnaldo Carvalho de Melo (4):
perf header: Add section bounds checking to the fd read path
perf header: Validate string length before allocating in do_read_string()
perf header: Sanity check HEADER_EVENT_DESC
perf header: Validate bitmap size before allocating in do_read_bitmap()
tools/perf/util/header.c | 33 +++++++++++++++++++++++++++------
1 file changed, 27 insertions(+), 6 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] perf header: Add section bounds checking to the fd read path
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
@ 2026-04-14 20:48 ` Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 2/4] perf header: Validate string length before allocating in do_read_string() Arnaldo Carvalho de Melo
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-04-14 20:48 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
__do_read_buf() validates reads against ff->size (section size), but
__do_read_fd() had no such check, so a malformed perf.data with an
understated section size could cause reads past the end of the current
section into the next section's data.
Add the bounds check in __do_read(), the common caller of both helpers,
so it is enforced uniformly for both the fd and buf paths.
This requires two supporting changes:
- perf_file_section__process(): initialize ff->offset to 0 so it
tracks bytes consumed from the section start (consistent with the
buf path), rather than the absolute file position.
- process_build_id(): use lseek(ff->fd, 0, SEEK_CUR) to discover
the current file position instead of reading ff->offset.
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
| 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f30e48eb3fc32da2..13bbf8df15f66cab 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -213,23 +213,23 @@ static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size)
if (ret != size)
return ret < 0 ? (int)ret : -1;
+ ff->offset += size;
return 0;
}
static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size)
{
- if (size > (ssize_t)ff->size - ff->offset)
- return -1;
-
memcpy(addr, ff->buf + ff->offset, size);
ff->offset += size;
return 0;
-
}
static int __do_read(struct feat_fd *ff, void *addr, ssize_t size)
{
+ if (size > (ssize_t)ff->size - ff->offset)
+ return -1;
+
if (!ff->buf)
return __do_read_fd(ff, addr, size);
return __do_read_buf(ff, addr, size);
@@ -2713,7 +2713,12 @@ static int process_tracing_data(struct feat_fd *ff __maybe_unused, void *data __
static int process_build_id(struct feat_fd *ff, void *data __maybe_unused)
{
- if (perf_header__read_build_ids(ff->ph, ff->fd, ff->offset, ff->size))
+ off_t offset = lseek(ff->fd, 0, SEEK_CUR);
+
+ if (offset == (off_t)-1)
+ return -1;
+
+ if (perf_header__read_build_ids(ff->ph, ff->fd, offset, ff->size))
pr_debug("Failed to read buildids, continuing...\n");
return 0;
}
@@ -4687,7 +4692,7 @@ static int perf_file_section__process(struct perf_file_section *section,
.fd = fd,
.ph = ph,
.size = section->size,
- .offset = section->offset,
+ .offset = 0,
};
if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] perf header: Validate string length before allocating in do_read_string()
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 1/4] perf header: Add section bounds checking to the fd read path Arnaldo Carvalho de Melo
@ 2026-04-14 20:48 ` Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 3/4] perf header: Sanity check HEADER_EVENT_DESC Arnaldo Carvalho de Melo
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-04-14 20:48 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
do_read_string() reads a u32 length from the file and immediately
allocates that many bytes. A crafted perf.data could claim a huge
string length, triggering a large allocation that would only be freed
moments later when __do_read() rejects the read against the section
bounds.
Check len against the remaining section size before the malloc().
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
| 3 +++
1 file changed, 3 insertions(+)
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 13bbf8df15f66cab..c27ed90727ea6629 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -269,6 +269,9 @@ static char *do_read_string(struct feat_fd *ff)
if (do_read_u32(ff, &len))
return NULL;
+ if (len > ff->size - ff->offset)
+ return NULL;
+
buf = malloc(len);
if (!buf)
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] perf header: Sanity check HEADER_EVENT_DESC
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 1/4] perf header: Add section bounds checking to the fd read path Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 2/4] perf header: Validate string length before allocating in do_read_string() Arnaldo Carvalho de Melo
@ 2026-04-14 20:48 ` Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 4/4] perf header: Validate bitmap size before allocating in do_read_bitmap() Arnaldo Carvalho de Melo
2026-04-16 8:24 ` [PATCHES 0/4] More perf.data header validation James Clark
4 siblings, 0 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-04-14 20:48 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
read_event_desc() reads nre (event count), sz (attr size), and nr
(IDs per event) from the file and uses them to control allocations
and loops without validating them against the section size.
A crafted perf.data could trigger large allocations or many loop
iterations before __do_read() eventually rejects the reads.
Add bounds checks:
- Reject sz == 0 or sz exceeding the section size.
- Check that nre events fit in the remaining section, using the
minimum per-event footprint of sz + sizeof(u32).
- Check that nr IDs fit in the remaining section before allocating.
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
| 10 ++++++++++
1 file changed, 10 insertions(+)
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index c27ed90727ea6629..3302748bac786fdf 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2141,6 +2141,13 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
if (do_read_u32(ff, &sz))
goto error;
+ /*
+ * The minimum section footprint per event is sz bytes for the attr
+ * plus a u32 for the id count, check that nre events fit.
+ */
+ if (sz == 0 || sz > ff->size || nre > (ff->size - ff->offset) / (sz + sizeof(u32)))
+ goto error;
+
/* buffer to hold on file attr struct */
buf = malloc(sz);
if (!buf)
@@ -2186,6 +2193,9 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
if (!nr)
continue;
+ if (nr > (ff->size - ff->offset) / sizeof(*id))
+ goto error;
+
id = calloc(nr, sizeof(*id));
if (!id)
goto error;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] perf header: Validate bitmap size before allocating in do_read_bitmap()
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
` (2 preceding siblings ...)
2026-04-14 20:48 ` [PATCH 3/4] perf header: Sanity check HEADER_EVENT_DESC Arnaldo Carvalho de Melo
@ 2026-04-14 20:48 ` Arnaldo Carvalho de Melo
2026-04-16 8:24 ` [PATCHES 0/4] More perf.data header validation James Clark
4 siblings, 0 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-04-14 20:48 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
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.
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.
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
| 3 +++
1 file changed, 3 insertions(+)
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 3302748bac786fdf..f2d0b8408cc29744 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -300,6 +300,9 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
if (ret)
return ret;
+ if (BITS_TO_U64(size) > (ff->size - ff->offset) / sizeof(u64))
+ return -1;
+
set = bitmap_zalloc(size);
if (!set)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCHES 0/4] More perf.data header validation
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
` (3 preceding siblings ...)
2026-04-14 20:48 ` [PATCH 4/4] perf header: Validate bitmap size before allocating in do_read_bitmap() Arnaldo Carvalho de Melo
@ 2026-04-16 8:24 ` James Clark
4 siblings, 0 replies; 6+ messages in thread
From: James Clark @ 2026-04-16 8:24 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Kan Liang, Clark Williams, linux-kernel,
linux-perf-users, Namhyung Kim
On 14/04/2026 21:48, Arnaldo Carvalho de Melo wrote:
> Hi,
>
> This is picking up from what was reported in the previous
> series, pre-existing lack of perf.data file validation, processing files
> and buffers in header.c in a similar fashion.
>
> There is more to process in the trace data, but that is a
> different can of worms that needs to be dealt with in a similar,
> upcoming patch series,
>
> This is probably 7.2 material, but if feeling this can still
> sneak into 7.1, feel free to do it :-)
>
> Now lets see what Sashiko discovers while I still don't have it
> running locally right after Claude, before submitting it publicly, which
> will soon happen :-)
If only checkpatch.pl ran Sashiko automatically... It would be one less
box to tick to get it right, of the many many boxes.
>
> - Arnaldo
>
> Arnaldo Carvalho de Melo (4):
> perf header: Add section bounds checking to the fd read path
> perf header: Validate string length before allocating in do_read_string()
> perf header: Sanity check HEADER_EVENT_DESC
> perf header: Validate bitmap size before allocating in do_read_bitmap()
>
> tools/perf/util/header.c | 33 +++++++++++++++++++++++++++------
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-16 8:24 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-14 20:48 [PATCHES 0/4] More perf.data header validation Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 1/4] perf header: Add section bounds checking to the fd read path Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 2/4] perf header: Validate string length before allocating in do_read_string() Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 3/4] perf header: Sanity check HEADER_EVENT_DESC Arnaldo Carvalho de Melo
2026-04-14 20:48 ` [PATCH 4/4] perf header: Validate bitmap size before allocating in do_read_bitmap() Arnaldo Carvalho de Melo
2026-04-16 8:24 ` [PATCHES 0/4] More perf.data header validation James Clark
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox