Re: [PATCH v2] perf header: Validate build_id filename length to prevent buffer overflow

Ian Rogers
2026-04-02T15:34:02Z

On Wed, Apr 1, 2026 at 3:12 PM Ian Rogers <irogers@google.com> wrote:
>
> On Wed, Apr 1, 2026 at 2:53 PM SeungJu Cheon <suunj1331@gmail.com> wrote:
> >
> > The build_id parsing functions calculate a filename length from the
> > event header size and read directly into a stack buffer of PATH_MAX
> > bytes without bounds checking. A malformed perf.data file with a
> > crafted header.size can cause the length to be negative or exceed
> > PATH_MAX, resulting in a stack buffer overflow.
> >
> > Add bounds checking for the filename length in both
> > perf_header__read_build_ids() and the ABI quirk variant. Print a
> > warning message when invalid length is detected.
> >
> > Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
>
> Reviewed-by: Ian Rogers <irogers@google.com>

Sashiko spotted some additional nits:
https://sashiko.dev/#/patchset/20260401215310.348463-1-suunj1331%40gmail.com
printf flags, potential for no '\0' termination and reads of
uninitialized memory.

Thanks,
Ian

> Thanks,
> Ian
>
> > ---
> > v2:
> > - Add warning message when invalid filename length detected
> > ---
> > tools/perf/util/header.c | 10 ++++++++++
> > 1 file changed, 10 insertions(+)
> >
> > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> > index 9142a8ba4019..132d360d716a 100644
> > --- a/tools/perf/util/header.c
> > +++ b/tools/perf/util/header.c
> > @@ -2545,6 +2545,11 @@ static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
> > perf_event_header__bswap(&old_bev.header);
> >
> > len = old_bev.header.size - sizeof(old_bev);
> > + if (len < 0 || len >= PATH_MAX) {
> > + pr_warning("invalid build_id filename length %d\n", len);
> > + return -1;
> > + }
> > +
> > if (readn(input, filename, len) != len)
> > return -1;
> >
> > @@ -2587,6 +2592,11 @@ static int perf_header__read_build_ids(struct perf_header *header,
> > perf_event_header__bswap(&bev.header);
> >
> > len = bev.header.size - sizeof(bev);
> > + if (len < 0 || len >= PATH_MAX) {
> > + pr_warning("invalid build_id filename length %d\n", len);
> > + goto out;
> > + }
> > +
> > if (readn(input, filename, len) != len)
> > goto out;
> > /*
> > --
> > 2.52.0
> >