All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Arnaldo Carvalho de Melo" <acme@kernel.org>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH 23/23] perf symbols: Add bounds checks to read_build_id() note iteration in minimal build
Date: Wed, 10 Jun 2026 20:15:02 +0000	[thread overview]
Message-ID: <20260610201503.01EBD1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260610195157.2091137-24-acme@kernel.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] Malicious ELF files with a crafted `p_filesz` of -1 bypass size checks and lead to a null pointer dereference or severe out-of-bounds memory access in `read_build_id()`.
- [High] Copy-paste typo clobbers the `p_filesz` field when byte-swapping 32-bit ELF program headers.
- [High] `sysfs__read_build_id()` fails to correctly read sysfs files due to reliance on exact `fstat()` sizes.
--

commit 952d244acf9e87676b56a5f5142736595a4fdb14
Author: Arnaldo Carvalho de Melo <acme@redhat.com>

perf symbols: Add bounds checks to read_build_id() note iteration in minimal build

This commit adds bounds checking to read_build_id() in the minimal ELF parser.
It validates namesz and descsz individually against the remaining data before
advancing the pointer to prevent out-of-bounds reads from malformed ELF files.

> diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
> index 8221dc9868f7c..091071d06416e 100644
> --- a/tools/perf/util/symbol-minimal.c
> +++ b/tools/perf/util/symbol-minimal.c
[ ... ]
> @@ -44,7 +45,7 @@ static int read_build_id(void *note_data, size_t note_len, struct build_id *bid,
>  	ptr = note_data;
>  	while ((ptr + sizeof(*nhdr)) < (note_data + note_len)) {
>  		const char *name;
> -		size_t namesz, descsz;
> +		size_t namesz, descsz, remaining;
>  
>  		nhdr = ptr;
>  		if (need_swap) {

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under review,
but there is a severe out-of-bounds memory access or null pointer dereference
possible here.

If note_data is NULL and note_len is -1 (which casts to the maximum size), ptr
will be NULL and this code will deference a NULL pointer when reading
nhdr->n_namesz.

This state can be reached from filename__read_build_id() if a malicious ELF
file crafts p_filesz to be -1:

tools/perf/util/symbol-minimal.c:filename__read_build_id() {
    ...
    p_filesz = elf32 ? hdrs.phdr32[i].p_filesz : hdrs.phdr64[i].p_filesz;
    if (p_filesz > buf_size) {
        ...
        tmp = realloc(buf, buf_size);
        ...
    }
    ...
    if (read(fd, buf, p_filesz) != p_filesz)
        goto out_free;

    ret = read_build_id(buf, p_filesz, bid, need_swap);
    ...
}

Because p_filesz is evaluated as a signed ssize_t, -1 is less than buf_size
(which is 0 initially), bypassing the memory allocation and leaving buf as NULL.

The error check read(fd, buf, p_filesz) != p_filesz is also bypassed because
read(fd, NULL, -1) returns -1, which matches p_filesz.

This passes note_data = NULL and note_len = -1 into read_build_id().

Could we add stricter bounds checking on p_filesz in filename__read_build_id()
to prevent this?

[ ... ]

[Severity: High]
This isn't a bug introduced by this patch, but I noticed a copy-paste typo in
filename__read_build_id() when byte-swapping 32-bit ELF program headers.

tools/perf/util/symbol-minimal.c:filename__read_build_id() {
    ...
    if (need_swap) {
        if (elf32) {
            hdrs.phdr32[i].p_type = bswap_32(hdrs.phdr32[i].p_type);
            hdrs.phdr32[i].p_offset = bswap_32(hdrs.phdr32[i].p_offset);
            hdrs.phdr32[i].p_filesz = bswap_32(hdrs.phdr32[i].p_offset);
        ...
    }
    ...
}

The code correctly swaps p_offset, but then assigns the swapped p_offset value
to p_filesz, instead of swapping the actual p_filesz field. This reverts the
byte swap and clobbers p_filesz with the original un-swapped p_offset.

Could this be corrected to swap hdrs.phdr32[i].p_filesz?


[Severity: High]
This is another pre-existing issue not introduced by this patch, but
sysfs__read_build_id() appears to rely on exact fstat() sizes.

tools/perf/util/symbol-minimal.c:sysfs__read_build_id() {
    ...
    if (fstat(fd, &stbuf) < 0)
        goto out;

    buf_size = stbuf.st_size;
    buf = malloc(buf_size);
    ...
    if (read(fd, buf, buf_size) != (ssize_t) buf_size)
        goto out_free;
    ...
}

Sysfs pseudo-files often report inaccurate lengths via st_size (like 0 or 4096),
regardless of their actual content size. 

By requiring the bytes read to strictly match buf_size, won't this
systematically fail for sysfs pseudo-files and incorrectly discard valid build
IDs?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260610195157.2091137-1-acme@kernel.org?part=23

      reply	other threads:[~2026-06-10 20:15 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 19:51 [PATCHES v1 00/23] perf tools: Fix OOB accesses, leaks, and missing bounds checks across pmu/symbols/bpf/hwmon Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 01/23] perf pmu: Fix pmu_id() heap underwrite on empty identifier file Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 02/23] perf pmu: Fix perf_pmu__parse_scale/unit() OOB access on empty sysfs file Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 03/23] tools lib api: Fix missing null termination in filename__read_int/ull() Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 04/23] perf symbols: Fix signed overflow in sysfs__read_build_id() size check Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 05/23] perf symbols: Bounds-check .gnu_debuglink section data Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 06/23] perf tools: Use mkostemp() for O_CLOEXEC on temporary files Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 07/23] perf intel-pt: Fix snprintf size tracking bug in insn decoder Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 08/23] perf tools: Fix thread__set_comm_from_proc() on empty comm file Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 09/23] perf hwmon: Fix off-by-one null termination on sysfs reads Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 10/23] perf hwmon: Use scnprintf() in hwmon_pmu__for_each_event() Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 11/23] perf hwmon: Fix parse_hwmon_filename() strlcpy buffer overflow Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 12/23] perf symbols: Bounds-check descsz in sysfs__read_build_id() GNU fallback Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 13/23] perf tools: Fix uninitialized pathname on uncompressed fallback in filename__decompress() Arnaldo Carvalho de Melo
2026-06-10 20:08   ` sashiko-bot
2026-06-10 21:52     ` Arnaldo Carvalho de Melo
2026-06-10 22:16       ` Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 14/23] perf hwmon: Guard label read against empty or failed reads Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 15/23] perf pmu: Use scnprintf() in format_alias() Arnaldo Carvalho de Melo
2026-06-10 20:05   ` sashiko-bot
2026-06-10 19:51 ` [PATCH 16/23] perf tools: Use snprintf() in dso__read_running_kernel_build_id() Arnaldo Carvalho de Melo
2026-06-10 20:10   ` sashiko-bot
2026-06-10 19:51 ` [PATCH 17/23] tools lib api: Fix filename__write_int() writing uninitialized stack data Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 18/23] tools lib api: Fix mount_overload() snprintf truncation and toupper range Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 19/23] perf bpf: Add NULL check for btf__type_by_id() in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
2026-06-10 20:14   ` sashiko-bot
2026-06-10 19:51 ` [PATCH 20/23] perf bpf: Fix map data leak in bpf_metadata_create() on alloc failure Arnaldo Carvalho de Melo
2026-06-10 20:12   ` sashiko-bot
2026-06-10 19:51 ` [PATCH 21/23] perf bpf: Fix metadata leak in perf_env__add_bpf_info() on duplicate insert Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 22/23] perf symbols: Add bounds checks to elf_read_build_id() note iteration Arnaldo Carvalho de Melo
2026-06-10 19:51 ` [PATCH 23/23] perf symbols: Add bounds checks to read_build_id() note iteration in minimal build Arnaldo Carvalho de Melo
2026-06-10 20:15   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260610201503.01EBD1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=acme@kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.