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

Namhyung Kim
2026-04-02T17:59:27Z

Hello,

On Thu, Apr 02, 2026 at 06:53:10AM +0900, SeungJu Cheon 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>
> ---
> 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;

I got this errors:

In file included from util/header.c:38:
util/header.c: In function 'perf_header__read_build_ids_abi_quirk':
util/header.c:2549:36: error: format '%d' expects argument of type 'int', but argument 4 has type 'ssize_t' {aka 'long int'} [-Werror=format
=]
2549 | pr_warning("invalid build_id filename length %d\n", len);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
util/debug.h:20:21: note: in definition of macro 'pr_fmt'
20 | #define pr_fmt(fmt) fmt
| ^~~
util/header.c:2549:25: note: in expansion of macro 'pr_warning'
2549 | pr_warning("invalid build_id filename length %d\n", len);
| ^~~~~~~~~~
util/header.c:2549:71: note: format string is defined here
2549 | pr_warning("invalid build_id filename length %d\n", len);
| ~^
| |
| int
| %ld

Please make sure it builds before sending patches. Hopefully we can run
perf test before and after your changes to see if there's anything
broken.

I'll fix it up this time.

Thanks,
Namhyung

> + }
> +
> 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
>