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
prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox