* [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm
@ 2026-06-12 0:34 Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 01/15] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
` (14 more replies)
0 siblings, 15 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo
Hi,
Fifteen more pre-existing bugs found by sashiko-bot during AI-assisted
code review. All are independent of the perf-data-validation hardening
series -- they are latent bugs in surrounding code exposed during review.
The fixes are grouped by subsystem:
ELF/build-id parsing in the no-libelf path (patches 1-3):
symbol-minimal.c carries a copy-paste typo that byte-swaps p_offset
instead of p_filesz for 32-bit ELF. The ssize_t p_filesz value is
used without checking for negative, and sysfs__read_build_id() trusts
fstat() on sysfs pseudo-files that report incorrect sizes. Replaced
with a fixed stack buffer and single read(), matching symbol-elf.c.
ELF note iteration (patch 4):
sysfs__read_build_id() in the libelf path can loop forever when a
note section contains zero-filled entries (namesz + descsz == 0).
Break when no progress can be made.
DSO decompression and open (patches 5-6):
dso__get_filename() copies a decompressed path with strcpy() into a
potentially shorter heap buffer. filename__decompress() fails to set
the error code on the uncompressed fallback path, leaving callers
with a stale errno.
Buffer overflow in root_dir path construction (patch 7):
machine.c and symbol.c use sprintf() to build paths with root_dir,
which can overflow the fixed-size buffer. Switch to snprintf().
hwmon fd check (patch 8):
hwmon_pmu__describe_items() tests fd > 0, rejecting the valid fd 0.
Undefined behavior in perf sched (patch 9):
map__findnew_thread() uses (void*)1 as a sentinel for colored threads.
This value gets dereferenced as a struct pointer and passed to free()
on cleanup. Replace with a proper allocation and a boolean color flag.
BPF metadata validation (patches 10-12):
synthesize_bpf_prog_name() trusts func_info_rec_size and sub_id from
perf.data without validation. bpf_metadata_alloc() stores the event
size in a __u16 without overflow checking. bpil_offs_to_addr()
converts untrusted offsets to heap pointers without bounds checking.
Memory leak in c2c (patch 13):
c2c hist entries register format list entries but never unregister
them on free, leaking the list nodes.
O_NONBLOCK for untrusted paths (patch 14):
open() calls that process paths from perf.data events can hang on
FIFOs or device nodes planted by a crafted file. Add O_NONBLOCK as
defense-in-depth on these foreign file opens.
CoreSight ETM CPU ID validation (patch 15):
cs_etm__process_auxtrace_info_full() compares an unsigned CPU ID
from perf.data metadata against a signed int without range checking.
A large unsigned value wraps negative, bypassing the bounds check.
Build-tested with gcc and clang. Passes perf test on x86_64.
Arnaldo Carvalho de Melo (15):
perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz
perf symbols: Validate p_filesz before use in filename__read_build_id()
perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build
perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id()
perf dso: Fix heap overflow in dso__get_filename() on decompressed path
perf dso: Set error code when open() fails on uncompressed fallback path
perf tools: Use snprintf() for root_dir path construction
perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items()
perf sched: Replace (void*)1 sentinel with proper runtime allocation
perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
perf bpf: Reject oversized BPF metadata events that truncate header.size
perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
perf c2c: Free format list entries when releasing c2c hist entries
perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths
perf cs-etm: Reject CPU IDs that would overflow signed comparison
tools/perf/builtin-c2c.c | 1 +
tools/perf/builtin-sched.c | 23 ++++++++++++-----
tools/perf/util/bpf-event.c | 13 +++++++++-
tools/perf/util/bpf-utils.c | 14 +++++++++++
tools/perf/util/cs-etm.c | 9 ++++++-
tools/perf/util/dso.c | 18 +++++++++++---
tools/perf/util/hwmon_pmu.c | 2 +-
tools/perf/util/machine.c | 2 +-
tools/perf/util/symbol-elf.c | 10 +++++---
tools/perf/util/symbol-minimal.c | 54 ++++++++++++++++++++++++----------------
tools/perf/util/symbol.c | 2 +-
11 files changed, 108 insertions(+), 40 deletions(-)
Developed with AI assistance (Claude/sashiko), tagged in commits.
Thanks,
- Arnaldo
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/15] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 02/15] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
` (13 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
filename__read_build_id() byte-swaps 32-bit ELF program headers on
cross-endian files, but line 178 passes p_offset to bswap_32() instead
of p_filesz:
hdrs.phdr32[i].p_filesz = bswap_32(hdrs.phdr32[i].p_offset);
This clobbers p_filesz with the already-swapped p_offset value. The
64-bit path on line 182 is correct and swaps p_filesz from p_filesz.
The consequence is that the PT_NOTE segment read uses the wrong size,
which can cause either a short read (missing the build-id) or an
oversized read (reading past the segment into adjacent data).
Fix by swapping the correct field.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: fef8f648bb47726d ("perf symbol: Fix use-after-free in filename__read_build_id")
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/symbol-minimal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 091071d06416e290..f4b0a711a62cf3de 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -175,7 +175,7 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
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);
+ hdrs.phdr32[i].p_filesz = bswap_32(hdrs.phdr32[i].p_filesz);
} else {
hdrs.phdr64[i].p_type = bswap_32(hdrs.phdr64[i].p_type);
hdrs.phdr64[i].p_offset = bswap_64(hdrs.phdr64[i].p_offset);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/15] perf symbols: Validate p_filesz before use in filename__read_build_id()
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 01/15] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build Arnaldo Carvalho de Melo
` (12 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
filename__read_build_id() stores ELF p_filesz in a ssize_t variable.
A crafted 32-bit ELF with p_filesz = 0xFFFFFFFF produces ssize_t value
-1. The comparison `p_filesz > buf_size` evaluates false because signed
-1 is less than any non-negative buf_size, so the realloc is skipped and
buf remains NULL.
The subsequent read(fd, NULL, -1) returns -1, which equals p_filesz,
passing the error check. read_build_id() then dereferences the NULL
buffer.
Add an explicit check for p_filesz <= 0 before using the value,
catching both zero-length and sign-wrapped negative sizes from crafted
ELF files.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: ba0b7081f7a521d7 ("perf symbol-minimal: Fix ehdr reading in filename__read_build_id")
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/symbol-minimal.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index f4b0a711a62cf3de..0a71d146395271a6 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -186,6 +186,9 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
continue;
p_filesz = elf32 ? hdrs.phdr32[i].p_filesz : hdrs.phdr64[i].p_filesz;
+ /* ssize_t can go negative with crafted ELF p_filesz values */
+ if (p_filesz <= 0)
+ continue;
if (p_filesz > buf_size) {
void *tmp;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 01/15] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 02/15] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:47 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 04/15] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
` (11 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
sysfs__read_build_id() in the no-libelf build path uses fstat() to get
the file size and then allocates an exact-sized buffer. Sysfs pseudo-
files (/sys/kernel/notes) often report st_size=0 or a page-sized value
(4096) regardless of actual content. When st_size is 0, malloc(0)
returns a zero-sized allocation and read(fd, buf, 0) returns 0, which
matches the expected (ssize_t)buf_size check, then read_build_id() is
called with a zero-length buffer and never finds any notes.
Replace the fstat + malloc approach with a fixed BUFSIZ stack buffer and
a single read(), matching the strategy used by the libelf-based
sysfs__read_build_id() in symbol-elf.c. This also eliminates the
malloc/free overhead for what is always a small sysfs file.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: b691f64360ecec49 ("perf symbols: Implement poor man's ELF parser")
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/symbol-minimal.c | 41 +++++++++++++++++++-------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 0a71d146395271a6..ea2de3d50d33cf33 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -220,29 +220,36 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
{
int fd;
int ret = -1;
- struct stat stbuf;
- size_t buf_size;
- void *buf;
+ /*
+ * read_build_id() casts this buffer to a u32 note header pointer,
+ * so it must be aligned for u32 access.
+ *
+ * Accessing a char[] through a u32* is technically type-punning
+ * under C strict aliasing rules, but perf unconditionally builds
+ * with -fno-strict-aliasing (Makefile.config), so this is safe.
+ *
+ * This file is only compiled when libelf is not available — the
+ * common case uses the libelf-based path in symbol-elf.c instead.
+ */
+ char buf[BUFSIZ] __aligned(4);
+ ssize_t len;
fd = open(filename, O_RDONLY);
if (fd < 0)
return -1;
- if (fstat(fd, &stbuf) < 0)
- goto out;
-
- buf_size = stbuf.st_size;
- buf = malloc(buf_size);
- if (buf == NULL)
- goto out;
-
- if (read(fd, buf, buf_size) != (ssize_t) buf_size)
- goto out_free;
+ /*
+ * Use a fixed buffer and a single read() instead of fstat() + malloc(),
+ * because sysfs pseudo-files often report st_size=0 or 4096
+ * regardless of actual content size.
+ *
+ * BUFSIZ (8192) is more than sufficient: a sysfs build-id note is
+ * ~36 bytes (12-byte note header + 4-byte "GNU" name + 20-byte SHA1).
+ */
+ len = read(fd, buf, sizeof(buf));
+ if (len > 0)
+ ret = read_build_id(buf, len, bid, false);
- ret = read_build_id(buf, buf_size, bid, false);
-out_free:
- free(buf);
-out:
close(fd);
return ret;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/15] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id()
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (2 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 05/15] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
` (10 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
sysfs__read_build_id() iterates ELF note headers from sysfs files in a
while(1) loop. If the file contains a zero-filled note header (both
n_namesz and n_descsz are 0), the code computes n = namesz + descsz = 0
and calls read(fd, bf, 0). read() with count 0 returns 0, which
matches the expected (ssize_t)n value, so the error check passes and
the loop repeats — reading the same zero bytes and spinning forever.
This can happen with corrupted or zero-padded sysfs pseudo-files.
Add a check for n == 0 before the read, since no valid ELF note has
both name and description of zero length.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: f1617b40596cb341 ("perf symbols: Record the build_ids of kernel modules too")
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/symbol-elf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index d84e2e031d430cf5..dc48e2d2763379b9 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -995,6 +995,9 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
} else {
n = namesz + descsz;
}
+ /* no valid note has both namesz and descsz zero */
+ if (n == 0)
+ break;
if (read(fd, bf, n) != (ssize_t)n)
break;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/15] perf dso: Fix heap overflow in dso__get_filename() on decompressed path
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (3 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 04/15] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
` (9 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
dso__get_filename() allocates name with malloc(PATH_MAX), but the
dso__filename_with_chroot() path replaces name with an asprintf'd
exact-size string (e.g. 8 bytes for "/a/b.ko"). When the DSO needs
decompression, dso__decompress_kmodule_path() writes the temp path
("/tmp/perf-kmod-XXXXXX", 22 bytes) into newpath, and strcpy(name,
newpath) overflows the smaller allocation.
Replace the strcpy with strdup(newpath) + free(name) so the buffer
is always correctly sized for its content.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 1d6b3c9ba756a513 ("perf tools: Decompress kernel module when reading DSO data")
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/dso.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 5d017975873817ec..511921bd901d8145 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -603,8 +603,15 @@ static char *dso__get_filename(struct dso *dso, const char *root_dir,
/* empty pathname means file wasn't actually compressed */
if (newpath[0] != '\0') {
+ char *tmp = strdup(newpath);
+
+ if (!tmp) {
+ unlink(newpath);
+ goto out;
+ }
+ free(name);
+ name = tmp;
*decomp = true;
- strcpy(name, newpath);
}
}
return name;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (4 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 05/15] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:54 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
` (8 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
filename__decompress() has an early return for files that are not
actually compressed, where it calls open() directly. When open()
fails, the function returns -1 but never sets *err. The caller chain
(decompress_kmodule → dso__decompress_kmodule_path → dso__get_filename)
then reads *dso__load_errno(dso) to set errno, but that field was never
populated, so errno gets a stale or zero value.
With errno=0, __open_dso() computes fd = -errno = 0, which is non-
negative, so callers treat fd 0 (stdin) as a valid DSO file descriptor.
Set *err = errno when open() fails on the uncompressed path, matching
the error handling on the compressed path at line 354.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 8b42b7e5e8b5692b ("perf tools: Add is_compressed callback to compressions array")
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/dso.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 511921bd901d8145..1a2fc6d18da74d6c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -344,9 +344,12 @@ int filename__decompress(const char *name, char *pathname,
* descriptor to the uncompressed file.
*/
if (!compressions[comp].is_compressed(name)) {
+ fd = open(name, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ *err = errno;
if (pathname && len > 0)
pathname[0] = '\0';
- return open(name, O_RDONLY | O_CLOEXEC);
+ return fd;
}
fd = mkostemp(tmpbuf, O_CLOEXEC);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (5 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 2:54 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 08/15] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
` (7 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Zhang Yanmin,
Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
get_kernel_version() in machine.c and dso__load_guest_kernel_sym() in
symbol.c use sprintf() to construct paths by prepending root_dir to
"/proc/version" and "/proc/kallsyms" respectively. Both write into
PATH_MAX stack buffers, but root_dir comes from --guestmount or KVM
configuration and is not length-checked. A root_dir at or near
PATH_MAX causes a stack buffer overflow.
Switch to snprintf() with sizeof(path) to prevent overflow.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: a1645ce12adb6c9c ("perf: 'perf kvm' tool for monitoring guest performance from host")
Cc: Zhang Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/machine.c | 2 +-
tools/perf/util/symbol.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index da1ad58758afd9d9..58fa57e3d1a15f37 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1336,7 +1336,7 @@ static char *get_kernel_version(const char *root_dir)
char *name, *tmp;
const char *prefix = "Linux version ";
- sprintf(version, "%s/proc/version", root_dir);
+ snprintf(version, sizeof(version), "%s/proc/version", root_dir);
file = fopen(version, "r");
if (!file)
return NULL;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 0c46b24ee0986059..c2328c9cec1565fc 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2275,7 +2275,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map)
if (!kallsyms_filename)
return -1;
} else {
- sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+ snprintf(path, sizeof(path), "%s/proc/kallsyms", machine->root_dir);
kallsyms_filename = path;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/15] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items()
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (6 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 09/15] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
` (6 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
hwmon_pmu__describe_items() checks 'if (fd > 0)' after openat(), which
incorrectly rejects fd 0. While fd 0 is normally stdin, if stdin has
been closed (common in daemon/service contexts), the kernel reuses fd 0
for the next open. With fd > 0, the sysfs file is not read and the fd
is leaked.
Change to 'if (fd >= 0)' to match the standard openat() error check.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 53cc0b351ec99278 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs")
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/hwmon_pmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c
index efd3067a2e591050..ed544dca70c380b2 100644
--- a/tools/perf/util/hwmon_pmu.c
+++ b/tools/perf/util/hwmon_pmu.c
@@ -435,7 +435,7 @@ static size_t hwmon_pmu__describe_items(struct hwmon_pmu *hwm, char *out_buf, si
hwmon_item_strs[bit],
is_alarm ? "_alarm" : "");
fd = openat(dir, buf, O_RDONLY);
- if (fd > 0) {
+ if (fd >= 0) {
ssize_t read_len = read(fd, buf, sizeof(buf) - 1);
while (read_len > 0 && buf[read_len - 1] == '\n')
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/15] perf sched: Replace (void*)1 sentinel with proper runtime allocation
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (7 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 08/15] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
` (5 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
map__findnew_thread() marks color-pid threads by storing (void*)1 as
the thread private data via thread__set_priv(). This sentinel value
causes two problems:
1. thread__get_runtime() returns (void*)1 as a struct thread_runtime
pointer. Any field access (e.g. tr->shortname) dereferences address
1, which is an unmapped page — immediate segfault.
2. cmd_sched() registers free() as the thread priv destructor, so thread
cleanup calls free((void*)1) — undefined behavior that corrupts the
heap on many allocators.
Fix by adding a 'color' flag to struct thread_runtime and allocating a
real runtime struct for color-pid threads. thread__has_color() now
checks the flag instead of relying on priv being non-NULL.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 58a606149c60d5da ("perf sched: Avoid union type punning undefined behavior")
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-sched.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5f16caebd9645da0..7fd63a9db4574fbf 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -274,6 +274,7 @@ struct thread_runtime {
u64 migrations;
int prio;
+ bool color;
};
/* per event run time data */
@@ -1589,22 +1590,32 @@ static int process_sched_wakeup_ignore(const struct perf_tool *tool __maybe_unus
static bool thread__has_color(struct thread *thread)
{
- return thread__priv(thread) != NULL;
+ struct thread_runtime *tr = thread__priv(thread);
+
+ return tr != NULL && tr->color;
}
static struct thread*
map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid, pid_t tid)
{
struct thread *thread = machine__findnew_thread(machine, pid, tid);
- bool color = false;
- if (!sched->map.color_pids || !thread || thread__priv(thread))
+ if (!sched->map.color_pids || !thread)
return thread;
- if (thread_map__has(sched->map.color_pids, tid))
- color = true;
+ /*
+ * Always check the color-pids map, even if thread__priv() is
+ * already set. COMM events processed before the first sched_switch
+ * allocate a thread_runtime via thread__get_runtime(), so priv is
+ * non-NULL before we ever get here. Skipping the check on non-NULL
+ * priv would prevent those threads from being colored.
+ */
+ if (thread_map__has(sched->map.color_pids, tid)) {
+ struct thread_runtime *tr = thread__get_runtime(thread);
- thread__set_priv(thread, color ? ((void*)1) : NULL);
+ if (tr)
+ tr->color = true;
+ }
return thread;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (8 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 09/15] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:52 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 11/15] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
` (4 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Song Liu, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
synthesize_bpf_prog_name() computes a pointer into the func_info array
using sub_id * info->func_info_rec_size without validating either value.
Both come from perf.data and are untrusted:
- A func_info_rec_size smaller than sizeof(struct bpf_func_info) means
the finfo pointer would reference a truncated entry, reading past it
into adjacent data.
- A sub_id >= nr_func_info computes an offset past the func_info buffer,
causing an out-of-bounds read.
Add bounds checks for both values before computing the pointer offset.
When validation fails, fall through to the non-BTF name path instead
of reading garbage.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 7b612e291a5affb1 ("perf tools: Synthesize PERF_RECORD_* for loaded BPF programs")
Cc: Song Liu <songliubraving@fb.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/bpf-event.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
index c4594969d7677238..fe6fbca508c5135c 100644
--- a/tools/perf/util/bpf-event.c
+++ b/tools/perf/util/bpf-event.c
@@ -143,7 +143,9 @@ static int synthesize_bpf_prog_name(char *buf, int size,
name_len = scnprintf(buf, size, "bpf_prog_");
name_len += snprintf_hex(buf + name_len, size - name_len,
prog_tags[sub_id], BPF_TAG_SIZE);
- if (btf) {
+ if (btf &&
+ info->func_info_rec_size >= sizeof(*finfo) &&
+ sub_id < info->nr_func_info) {
finfo = func_infos + sub_id * info->func_info_rec_size;
t = btf__type_by_id(btf, finfo->type_id);
if (t)
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/15] perf bpf: Reject oversized BPF metadata events that truncate header.size
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (9 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
` (3 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Blake Jones,
Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
bpf_metadata_alloc() computes event_size from the number of BPF metadata
variables and stores it in header.size, which is __u16. With 204 or
more .rodata variables prefixed "bpf_metadata_", event_size exceeds
65535 and silently truncates.
The truncated header.size causes synthesize_perf_record_bpf_metadata()
to allocate a buffer sized by the truncated value, then memcpy the full
event data into it — a heap buffer overflow.
Add a check that event_size fits in __u16 before proceeding. BPF
programs with that many metadata variables are exotic enough that
silently dropping the metadata is acceptable.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: ab38e84ba9a80581 ("perf record: collect BPF metadata from existing BPF programs")
Cc: Blake Jones <blakejones@google.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/bpf-event.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
index fe6fbca508c5135c..57d53ba848359e12 100644
--- a/tools/perf/util/bpf-event.c
+++ b/tools/perf/util/bpf-event.c
@@ -369,6 +369,15 @@ static struct bpf_metadata *bpf_metadata_alloc(__u32 nr_prog_tags,
event_size = sizeof(metadata->event->bpf_metadata) +
nr_variables * sizeof(metadata->event->bpf_metadata.entries[0]);
+ /*
+ * header.size is __u16. synthesize_perf_record_bpf_metadata()
+ * adds machine->id_hdr_size (up to ~64 bytes) after this, so
+ * leave headroom to prevent the final size from wrapping.
+ */
+ if (event_size > UINT16_MAX - 256) {
+ bpf_metadata_free(metadata);
+ return NULL;
+ }
metadata->event = zalloc(event_size);
if (!metadata->event) {
bpf_metadata_free(metadata);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (10 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 11/15] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:51 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
` (2 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Dave Marchevsky,
Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
bpil_offs_to_addr() converts offsets stored in perf.data's
bpf_prog_info_linear structure into heap pointers by adding the offset
to the data allocation base. The offsets come from untrusted file input
and are not validated against data_len.
If an offset exceeds data_len, the computed address points outside the
allocated data buffer. Callers like synthesize_bpf_prog_name() then
dereference prog_tags[sub_id] or func_info pointers, reading arbitrary
heap memory.
Add a bounds check: when an offset exceeds data_len, zero the field
and skip the conversion. This prevents out-of-bounds pointer
construction from crafted perf.data files.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 6ac22d036f86c4e2 ("perf bpf: Pull in bpf_program__get_prog_info_linear()")
Cc: Dave Marchevsky <davemarchevsky@fb.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/bpf-utils.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c
index d6d2c9c190f7afbf..98cf21a9113428dc 100644
--- a/tools/perf/util/bpf-utils.c
+++ b/tools/perf/util/bpf-utils.c
@@ -264,12 +264,26 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) {
const struct bpil_array_desc *desc = &bpil_array_desc[i];
__u64 addr, offs;
+ __u32 count, size;
if ((info_linear->arrays & (1UL << i)) == 0)
continue;
offs = bpf_prog_info_read_offset_u64(&info_linear->info,
desc->array_offset);
+ count = bpf_prog_info_read_offset_u32(&info_linear->info,
+ desc->count_offset);
+ size = bpf_prog_info_read_offset_u32(&info_linear->info,
+ desc->size_offset);
+ /* offset and extent from perf.data are untrusted — keep within data[] */
+ if (offs >= info_linear->data_len ||
+ (u64)count * size > info_linear->data_len - offs) {
+ bpf_prog_info_set_offset_u64(&info_linear->info,
+ desc->array_offset, 0);
+ bpf_prog_info_set_offset_u32(&info_linear->info,
+ desc->count_offset, 0);
+ continue;
+ }
addr = offs + ptr_to_u64(info_linear->data);
bpf_prog_info_set_offset_u64(&info_linear->info,
desc->array_offset, addr);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (11 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 0:58 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
c2c_hists__init() calls hpp_list__parse() which allocates and registers
format entries on hists->list. When c2c_he_free() destroys a c2c hist
entry, it deletes the histogram entries and frees the hists container but
never unregisters the format list entries, leaking them.
Call perf_hpp__reset_output_field() before freeing the hists to properly
unregister and free all format entries.
Fixes: f485e33c4543ac31 ("perf c2c report: Add cacheline hists processing")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/finding/41
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-c2c.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index e205f58b2f3d3786..07c7e8fb315e6cf3 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -185,6 +185,7 @@ static void c2c_he_free(void *he)
c2c_he = container_of(he, struct c2c_hist_entry, he);
if (c2c_he->hists) {
hists__delete_entries(&c2c_he->hists->hists);
+ perf_hpp__reset_output_field(&c2c_he->hists->list);
zfree(&c2c_he->hists);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (12 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 4:57 ` sashiko-bot
2026-06-12 5:52 ` Ian Rogers
2026-06-12 0:34 ` [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
14 siblings, 2 replies; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
DSO paths from perf.data MMAP events could reference FIFOs, device
nodes, or other special files. Opening such paths without O_NONBLOCK
can hang perf report/script indefinitely waiting for a writer or device.
Add O_NONBLOCK to all open() calls in the DSO symbol resolution paths:
filename__read_build_id(), filename__read_debuglink(), symsrc__init(),
do_open(), filename__decompress(), and __dso__read_symbol().
O_NONBLOCK is a no-op on regular files but prevents blocking on special
files, following the systemd "foreign file" convention. Also add missing
O_CLOEXEC flags in symbol-minimal.c for consistency.
Fixes: a08cae03f430b971 ("perf tools: Allow to close dso fd in case of open failure")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/finding/6
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/dso.c | 6 +++---
tools/perf/util/symbol-elf.c | 7 ++++---
tools/perf/util/symbol-minimal.c | 6 +++---
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 1a2fc6d18da74d6c..dc0c8b9c63017239 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -344,7 +344,7 @@ int filename__decompress(const char *name, char *pathname,
* descriptor to the uncompressed file.
*/
if (!compressions[comp].is_compressed(name)) {
- fd = open(name, O_RDONLY | O_CLOEXEC);
+ fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
*err = errno;
if (pathname && len > 0)
@@ -547,7 +547,7 @@ static void close_first_dso(void);
static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
{
do {
- int fd = open(name, O_RDONLY|O_CLOEXEC);
+ int fd = open(name, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
if (fd >= 0)
return fd;
@@ -1927,7 +1927,7 @@ static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename,
int saved_errno;
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
- fd = open(symfs_filename, O_RDONLY | O_CLOEXEC);
+ fd = open(symfs_filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
saved_errno = errno;
nsinfo__mountns_exit(&nsc);
if (fd < 0) {
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index dc48e2d2763379b9..01c7b09fc82bcddb 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -886,7 +886,8 @@ static int read_build_id(const char *filename, struct build_id *bid)
if (size < BUILD_ID_SIZE)
goto out;
- fd = open(filename, O_RDONLY | O_CLOEXEC);
+ /* O_NONBLOCK avoids hangs on FIFOs/devices from crafted perf.data paths */
+ fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
goto out;
@@ -1022,7 +1023,7 @@ int filename__read_debuglink(const char *filename, char *debuglink,
if (err >= 0)
goto out;
- fd = open(filename, O_RDONLY | O_CLOEXEC);
+ fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
goto out;
@@ -1187,7 +1188,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
type = dso__symtab_type(dso);
} else {
- fd = open(name, O_RDONLY | O_CLOEXEC);
+ fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0) {
*dso__load_errno(dso) = errno;
return -1;
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index ea2de3d50d33cf33..dc4a06b2a03ad3cb 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -118,7 +118,7 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
if (!is_regular_file(filename))
return errno == 0 ? -EWOULDBLOCK : -errno;
- fd = open(filename, O_RDONLY);
+ fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
return -1;
@@ -234,7 +234,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
char buf[BUFSIZ] __aligned(4);
ssize_t len;
- fd = open(filename, O_RDONLY);
+ fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
return -1;
@@ -257,7 +257,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
enum dso_binary_type type)
{
- int fd = open(name, O_RDONLY);
+ int fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0)
goto out_errno;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
` (13 preceding siblings ...)
2026-06-12 0:34 ` [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths Arnaldo Carvalho de Melo
@ 2026-06-12 0:34 ` Arnaldo Carvalho de Melo
2026-06-12 1:00 ` sashiko-bot
14 siblings, 1 reply; 25+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 0:34 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, James Clark,
Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
metadata[j][CS_ETM_CPU] is a u64 from perf.data, but the comparison
with max_cpu casts it to (int). A crafted value like 0xFFFFFFFF becomes
-1 after the cast, which compares less than max_cpu (0), so the queue
array is never sized to accommodate it. When the value is later passed
to cs_etm__get_queue(), it indexes queue_array with the original large
value, causing an out-of-bounds access.
Validate that CS_ETM_CPU fits in an int before using it in the signed
comparison.
Fixes: 57880a7966be510c ("perf: cs-etm: Allocate queues for all CPUs")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/finding/2
Cc: James Clark <james.clark@arm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/cs-etm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 5e92359f51a7cb87..d8876b8362056c98 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -6,6 +6,7 @@
* Author: Mathieu Poirier <mathieu.poirier@linaro.org>
*/
+#include <limits.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/coresight-pmu.h>
@@ -3468,7 +3469,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
goto err_free_metadata;
}
- if ((int) metadata[j][CS_ETM_CPU] > max_cpu)
+ /* CPU id comes from perf.data and must be a valid index */
+ if (metadata[j][CS_ETM_CPU] > INT_MAX) {
+ err = -EINVAL;
+ goto err_free_metadata;
+ }
+
+ if ((int)metadata[j][CS_ETM_CPU] > max_cpu)
max_cpu = metadata[j][CS_ETM_CPU];
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build
2026-06-12 0:34 ` [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build Arnaldo Carvalho de Melo
@ 2026-06-12 0:47 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 0:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Type punning via pointer casting from a declared character array to a struct pointer violates strict aliasing rules required for `tools/` code.
--
commit 712f0fc91e35c55d2c2445bb412251f7934f7642
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build
This commit replaces an fstat() and malloc() approach with a fixed stack
buffer and a single read() in sysfs__read_build_id(). This ensures proper
handling of sysfs pseudo-files that report a size of 0 or 4096 regardless
of actual content.
> diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
> index 0a71d14639527..ea2de3d50d33c 100644
> --- a/tools/perf/util/symbol-minimal.c
> +++ b/tools/perf/util/symbol-minimal.c
> @@ -220,29 +220,36 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> {
[ ... ]
> + /*
> + * read_build_id() casts this buffer to a u32 note header pointer,
> + * so it must be aligned for u32 access.
> + *
> + * Accessing a char[] through a u32* is technically type-punning
> + * under C strict aliasing rules, but perf unconditionally builds
> + * with -fno-strict-aliasing (Makefile.config), so this is safe.
> + *
> + * This file is only compiled when libelf is not available — the
> + * common case uses the libelf-based path in symbol-elf.c instead.
> + */
> + char buf[BUFSIZ] __aligned(4);
[Severity: Low]
While the comment notes that perf currently builds with -fno-strict-aliasing,
the tools directory guidelines require assuming standard -fstrict-aliasing
for all tools code.
Does casting this character array to an incompatible u32 struct pointer
inside read_build_id() violate the strict aliasing rules expected for this
subsystem?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=3
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
2026-06-12 0:34 ` [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
@ 2026-06-12 0:51 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 0:51 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Information leak of heap address due to incomplete offset sanitization.
--
commit a0507a1a42adbf8d7d5cf1288f8518eee273f578
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
This commit adds a bounds check to bpil_offs_to_addr() for offsets coming from
untrusted perf.data files. When an offset exceeds data_len, the offset fields
are zeroed out and the pointer conversion is skipped to prevent out-of-bounds
pointer construction.
> diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c
> --- a/tools/perf/util/bpf-utils.c
> +++ b/tools/perf/util/bpf-utils.c
[ ... ]
> @@ -264,12 +264,26 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
> for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) {
> const struct bpil_array_desc *desc = &bpil_array_desc[i];
> __u64 addr, offs;
> + __u32 count, size;
>
> if ((info_linear->arrays & (1UL << i)) == 0)
> continue;
>
> offs = bpf_prog_info_read_offset_u64(&info_linear->info,
> desc->array_offset);
> + count = bpf_prog_info_read_offset_u32(&info_linear->info,
> + desc->count_offset);
> + size = bpf_prog_info_read_offset_u32(&info_linear->info,
> + desc->size_offset);
> + /* offset and extent from perf.data are untrusted — keep within data[] */
> + if (offs >= info_linear->data_len ||
> + (u64)count * size > info_linear->data_len - offs) {
> + bpf_prog_info_set_offset_u64(&info_linear->info,
> + desc->array_offset, 0);
> + bpf_prog_info_set_offset_u32(&info_linear->info,
> + desc->count_offset, 0);
> + continue;
[Severity: Medium]
Does skipping this conversion without clearing the corresponding array bit
in info_linear->arrays leak the heap address later?
When the bounds check fails, the offset is set to 0, but the active array
bit remains set in the info_linear->arrays bitmask.
Later, if the tool rewrites the data (such as during perf inject or archive),
write_bpf_prog_info() will call bpil_addr_to_offs(), which processes all
arrays that still have their bits set. It subtracts the heap base pointer
(info_linear->data) from the array address.
Since the address was explicitly forced to 0 here, the calculation becomes
0 - ptr_to_u64(info_linear->data). This results in the two's complement of
the heap address, which is then saved into the bpf_prog_info struct and
written back out to the perf.data file.
Would it be safer to also clear the active array bit via
info_linear->arrays &= ~(1UL << i) when zeroing out these offsets?
> + }
> addr = offs + ptr_to_u64(info_linear->data);
> bpf_prog_info_set_offset_u64(&info_linear->info,
> desc->array_offset, addr);
> }
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=12
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
2026-06-12 0:34 ` [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
@ 2026-06-12 0:52 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 0:52 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Medium] Arbitrary memory read due to unvalidated array offsets in `bpil_offs_to_addr()` when array bits are unset
--
commit a163a7a43ee7ff41ce65cced45401ef40028fc1f
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
synthesize_bpf_prog_name() computes a pointer into the func_info array
using sub_id * info->func_info_rec_size without validating either value.
Both come from perf.data and are untrusted, so bounds checks are added
before computing the pointer offset.
> diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
> index c4594969d7677..fe6fbca508c51 100644
> --- a/tools/perf/util/bpf-event.c
> +++ b/tools/perf/util/bpf-event.c
> @@ -143,7 +143,9 @@ static int synthesize_bpf_prog_name(char *buf, int size,
> name_len = scnprintf(buf, size, "bpf_prog_");
> name_len += snprintf_hex(buf + name_len, size - name_len,
> prog_tags[sub_id], BPF_TAG_SIZE);
[Severity: Medium]
This is a pre-existing issue, but does casting info->prog_tags to a pointer
and dereferencing it here allow an arbitrary memory read if a malicious
perf.data is provided?
If an attacker clears the array bit in info_linear->arrays,
bpil_offs_to_addr() will silently skip converting or validating the offset:
tools/perf/util/bpf-utils.c:bpil_offs_to_addr() {
...
if ((info_linear->arrays & (1UL << i)) == 0)
continue;
...
}
This leaves the raw, untrusted 64-bit value from the file intact in
info->prog_tags.
> - if (btf) {
> + if (btf &&
> + info->func_info_rec_size >= sizeof(*finfo) &&
> + sub_id < info->nr_func_info) {
[Severity: Medium]
This is a pre-existing issue, but does info->func_info face the same
arbitrary memory read vulnerability?
The func_infos pointer is assigned from info->func_info earlier in
synthesize_bpf_prog_name(). If its array bit is cleared in
info_linear->arrays, it retains the untrusted value.
Since info->nr_func_info is also fully attacker-controlled in this
scenario, could an attacker bypass this bounds check and read from
an arbitrary address?
Similar unvalidated pointer accesses appear to happen in
__bpf_event__print_bpf_prog_info() when it casts info->jited_func_lens
and info->jited_ksyms to pointers.
> finfo = func_infos + sub_id * info->func_info_rec_size;
> t = btf__type_by_id(btf, finfo->type_id);
> if (t)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=10
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path
2026-06-12 0:34 ` [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
@ 2026-06-12 0:54 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 0:54 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Type punning by accessing a char array through an incompatible pointer type in tools/.
--
commit 4b3994ef70950d73fb48b1cdff6e7ffb7ee129d2
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf dso: Set error code when open() fails on uncompressed fallback path
filename__decompress() has an early return for files that are not
actually compressed, where it calls open() directly. When open()
fails, the function returns -1 but never sets *err, leading to a stale
or zero errno. This causes callers to treat fd 0 as a valid DSO file
descriptor.
> diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
> index 091071d06416e..ea2de3d50d33c 100644
> --- a/tools/perf/util/symbol-minimal.c
> +++ b/tools/perf/util/symbol-minimal.c
[ ... ]
> @@ -217,29 +220,36 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> {
> int fd;
> int ret = -1;
> - struct stat stbuf;
> - size_t buf_size;
> - void *buf;
> + /*
> + * read_build_id() casts this buffer to a u32 note header pointer,
> + * so it must be aligned for u32 access.
> + *
> + * Accessing a char[] through a u32* is technically type-punning
> + * under C strict aliasing rules, but perf unconditionally builds
> + * with -fno-strict-aliasing (Makefile.config), so this is safe.
> + *
> + * This file is only compiled when libelf is not available — the
> + * common case uses the libelf-based path in symbol-elf.c instead.
> + */
> + char buf[BUFSIZ] __aligned(4);
[Severity: Medium]
The comment mentions that perf unconditionally builds with
-fno-strict-aliasing, making this safe. However, do files under the tools/
directory generally assume standard -fstrict-aliasing?
When this character array is passed to read_build_id() and cast to an
incompatible structure pointer type:
sysfs__read_build_id()->read_build_id() {
nhdr = ptr;
if (need_swap) {
nhdr->n_namesz = bswap_32(nhdr->n_namesz);
Could this type punning lead to undefined behavior or compiler optimization
issues if standard compiler flags are used for tools?
> + ssize_t len;
>
> fd = open(filename, O_RDONLY);
> if (fd < 0)
> return -1;
>
> - if (fstat(fd, &stbuf) < 0)
> - goto out;
> + /*
> + * Use a fixed buffer and a single read() instead of fstat() + malloc(),
> + * because sysfs pseudo-files often report st_size=0 or 4096
> + * regardless of actual content size.
> + *
> + * BUFSIZ (8192) is more than sufficient: a sysfs build-id note is
> + * ~36 bytes (12-byte note header + 4-byte "GNU" name + 20-byte SHA1).
> + */
> + len = read(fd, buf, sizeof(buf));
> + if (len > 0)
> + ret = read_build_id(buf, len, bid, false);
>
> - buf_size = stbuf.st_size;
> - buf = malloc(buf_size);
> - if (buf == NULL)
> - goto out;
> -
> - if (read(fd, buf, buf_size) != (ssize_t) buf_size)
> - goto out_free;
> -
> - ret = read_build_id(buf, buf_size, bid, false);
> -out_free:
> - free(buf);
> -out:
> close(fd);
> return ret;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=6
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries
2026-06-12 0:34 ` [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
@ 2026-06-12 0:58 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 0:58 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Memory leak of inner `hist_entry` objects in `entries_in_array` when releasing outer cacheline entries in `c2c_he_free()`.
- [Medium] Memory leak of dynamically allocated format list entries on the error path in `he__get_c2c_hists()`.
--
commit 0bf603f26db9e5b4fcbe6b43bcf6b0d0f45e4807
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf c2c: Free format list entries when releasing c2c hist entries
This commit fixes a memory leak in c2c_he_free() by calling
perf_hpp__reset_output_field() before freeing the hists container. This
properly unregisters and frees all format entries that were allocated by
hpp_list__parse().
Closes: https://sashiko.dev/finding/41
> diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
> index e205f58b2f3d3..07c7e8fb315e6 100644
> --- a/tools/perf/builtin-c2c.c
> +++ b/tools/perf/builtin-c2c.c
> @@ -185,6 +185,7 @@ static void c2c_he_free(void *he)
> c2c_he = container_of(he, struct c2c_hist_entry, he);
> if (c2c_he->hists) {
> hists__delete_entries(&c2c_he->hists->hists);
[Severity: High]
This is a pre-existing issue, but does this adequately clear out the inner
entries?
During the tracking phase, node-level events are inserted into the inner
hists of each cacheline c2c_hist_entry, populating
hists->entries_in_array[0]. When perf c2c resorts the main cachelines, it
may merge entries and delete the redundant ones by invoking c2c_he_free().
At this stage, the inner hists of the redundant entries have not yet been
output-resorted, so their entries tree is empty. Because
hists__delete_entries() only cleans the empty entries tree, could the
subsequent zfree(&c2c_he->hists) leak all inner hist_entry objects in
entries_in_array[0] or entries_collapsed?
> + perf_hpp__reset_output_field(&c2c_he->hists->list);
> zfree(&c2c_he->hists);
> }
[Severity: Medium]
This is a pre-existing issue, but is there a similar leak of the format
list entries on the error path in he__get_c2c_hists()?
tools/perf/builtin-c2c.c:he__get_c2c_hists() {
...
ret = c2c_hists__init(hists, sort, nr_header_lines, env);
if (ret) {
c2c_he->hists = NULL;
free(hists);
return NULL;
}
...
}
If c2c_hists__init() fails partway through after appending some format
entries to hists->list, they don't seem to be cleared before freeing the
hists container. Should perf_hpp__reset_output_field() be called here as
well?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=13
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison
2026-06-12 0:34 ` [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
@ 2026-06-12 1:00 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 1:00 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Medium] The new bounds check allows `INT_MAX`, resulting in undefined behavior via signed integer overflow when calculating `max_cpu + 1`.
Pre-existing issues:
- [Critical] The calculation `sizeof(*metadata) * num_cpu` wraps around on 32-bit architectures, leading to a zero-sized allocation and massive out-of-bounds heap write.
- [High] Global metadata attributes are accessed from the event payload before verifying that the event buffer is large enough.
- [High] Unvalidated `sample.cpu` index leads to an out-of-bounds array access in `cs_etm__get_queue()` when triggered by `PERF_RECORD_AUX_OUTPUT_HW_ID` events.
--
commit bc723e7a90a3b64c38ed57e3f771d57c18e1dc9d
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf cs-etm: Reject CPU IDs that would overflow signed comparison
This commit fixes an out-of-bounds access in
cs_etm__process_auxtrace_info_full() caused by a cast from u64 to int. It
adds a validation check to ensure the CPU ID fits within an int before
performing a signed comparison against max_cpu.
Cc: James Clark <james.clark@arm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/finding/2
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 5e92359f51a7c..d8876b8362056 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -6,6 +6,7 @@
> * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
> */
>
> +#include <limits.h>
> #include <linux/bitfield.h>
> #include <linux/bitops.h>
> #include <linux/coresight-pmu.h>
[ ... ]
> @@ -3468,7 +3469,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
> goto err_free_metadata;
> }
>
> - if ((int) metadata[j][CS_ETM_CPU] > max_cpu)
> + /* CPU id comes from perf.data and must be a valid index */
> + if (metadata[j][CS_ETM_CPU] > INT_MAX) {
> + err = -EINVAL;
> + goto err_free_metadata;
> + }
[Severity: Medium]
Does this upper bound check still allow max_cpu to become INT_MAX?
If the trace provides exactly INT_MAX, max_cpu is set to INT_MAX. Later in
cs_etm__process_auxtrace_info_full(), it calls:
err = auxtrace_queues__init_nr(&etm->queues, max_cpu + 1);
Will computing INT_MAX + 1 cause a signed integer overflow?
[Severity: Critical]
This is a pre-existing issue, but I noticed a potential calculation overflow
earlier in cs_etm__process_auxtrace_info_full():
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
metadata = zalloc(sizeof(*metadata) * num_cpu);
On 32-bit platforms, could a crafted num_cpu (e.g., 1073741825) cause the
multiplication to wrap around to 4? If zalloc() succeeds with a tiny buffer,
wouldn't the subsequent loop:
for (int j = 0; j < num_cpu; j++) {
...
metadata[j] = cs_etm__create_meta_blk(...);
continuously write out-of-bounds into the undersized allocation?
[Severity: High]
This is a pre-existing issue, but is it possible to read past the end of the
event payload before its size is fully validated?
In cs_etm__process_auxtrace_info_full():
ptr = (u64 *) auxtrace_info->priv;
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
Since the initial perf_record_auxtrace_info size check only guarantees
16 bytes, and priv[] starts at offset 16, accessing ptr[CS_PMU_TYPE_CPUS]
reads from offset 24.
Could this access unmapped memory if the event is truncated?
[Severity: High]
This is a pre-existing issue, but is there an unvalidated index used for
queue array lookups?
When processing PERF_RECORD_AUX_OUTPUT_HW_ID events, sample.cpu is parsed
directly from the payload. It gets passed down the call chain:
cs_etm__process_aux_output_hw_id()
cs_etm__process_trace_id_v0_1()
cs_etm__get_queue()
Inside cs_etm__get_queue():
return etm->queues.queue_array[cpu].priv;
Since cpu comes directly from the trace data, could an arbitrarily large or
negative value cause an out-of-bounds read if it exceeds nr_queues?
> +
> + if ((int)metadata[j][CS_ETM_CPU] > max_cpu)
> max_cpu = metadata[j][CS_ETM_CPU];
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=15
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction
2026-06-12 0:34 ` [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
@ 2026-06-12 2:54 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 2:54 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Incomplete fix for stack buffer overflows caused by unbounded `--guestmount` arguments.
--
commit 7a512f0d1037b835700ec0c14aab087dcaf3e840
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf tools: Use snprintf() for root_dir path construction
This patch mitigates stack buffer overflows in get_kernel_version() and
dso__load_guest_kernel_sym() by replacing sprintf() with snprintf(). It
prevents unbounded root_dir inputs (from KVM configurations or
--guestmount) from overflowing the PATH_MAX stack buffers.
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index da1ad58758afd..58fa57e3d1a15 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -1336,7 +1336,7 @@ static char *get_kernel_version(const char *root_dir)
> char *name, *tmp;
> const char *prefix = "Linux version ";
>
> - sprintf(version, "%s/proc/version", root_dir);
> + snprintf(version, sizeof(version), "%s/proc/version", root_dir);
[Severity: High]
This isn't a bug introduced by this patch, but does the same overflow
vulnerability remain in other places that use symbol_conf.guestmount?
For example, in tools/perf/util/machine.c:machines__findnew(), the unbounded
path is formatted into a stack-allocated buffer:
if ((pid != HOST_KERNEL_ID) &&
(pid != DEFAULT_GUEST_KERNEL_ID) &&
(symbol_conf.guestmount)) {
sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
And in machines__create_guest_kernel_maps():
sprintf(path, "%s/%s/proc/kallsyms",
symbol_conf.guestmount,
namelist[i]->d_name);
Both format unbounded user input into a stack-allocated path buffer using
sprintf(). Should these also be converted to snprintf() to fully prevent
stack buffer overflows?
> file = fopen(version, "r");
> if (!file)
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=7
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths
2026-06-12 0:34 ` [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths Arnaldo Carvalho de Melo
@ 2026-06-12 4:57 ` sashiko-bot
2026-06-12 5:52 ` Ian Rogers
1 sibling, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-06-12 4:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The patch fails to comprehensively mitigate indefinite hangs caused by crafted perf.data DSO paths pointing to FIFOs because it misses numerous fallback, compression, and auxiliary code paths.
- [Low] Type punning via pointer casting violates the strict aliasing rule for tools code.
--
commit 8ad114a12f8caea55970c5c9b35f35f0df11e5b4
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths
DSO paths from perf.data MMAP events could reference FIFOs, device
nodes, or other special files. Opening such paths without O_NONBLOCK
can hang perf report/script indefinitely waiting for a writer or device.
Fixes: a08cae03f430b971 ("perf tools: Allow to close dso fd in case of open failure")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/finding/6
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> Add O_NONBLOCK to all open() calls in the DSO symbol resolution paths:
> filename__read_build_id(), filename__read_debuglink(), symsrc__init(),
> do_open(), filename__decompress(), and __dso__read_symbol().
[Severity: High]
This isn't a bug introduced by this patch, but are there several other
DSO resolution paths missing this protection?
For example, decompression checks seem to perform blocking open() calls
before filename__decompress() is reached:
- tools/perf/util/zlib.c:gzip_is_compressed()
- tools/perf/util/lzma.c:lzma_is_compressed()
Additionally, blocking opens appear to still be used in:
- tools/perf/util/symbol-elf.c:sysfs__read_build_id()
- tools/perf/util/capstone.c:symbol__disassemble_capstone_powerpc()
- tools/perf/util/unwind-libunwind.c:read_unwind_spec_debug_frame()
Since crafted perf.data paths ending in .xz or .gz might hit these checks
first, will they still cause an indefinite hang?
> diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
> index ea2de3d50d33c..dc4a06b2a03ad 100644
> --- a/tools/perf/util/symbol-minimal.c
> +++ b/tools/perf/util/symbol-minimal.c
[ ... ]
> @@ -234,7 +234,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> char buf[BUFSIZ] __aligned(4);
> ssize_t len;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> return -1;
[Severity: Low]
This is a pre-existing issue, but is it possible this function violates the
strict aliasing rule for tools code?
Later in this function, the char buffer is passed into read_build_id():
len = read(fd, buf, sizeof(buf));
if (len > 0)
ret = read_build_id(buf, len, bid, false);
If read_build_id() casts this buffer to a u32 struct pointer to read the
ELF note header, this would be type punning. Although perf is built with
-fno-strict-aliasing, tools code assumes standard -fstrict-aliasing per
the subsystem guidelines.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612003444.50723-1-acme@kernel.org?part=14
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths
2026-06-12 0:34 ` [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths Arnaldo Carvalho de Melo
2026-06-12 4:57 ` sashiko-bot
@ 2026-06-12 5:52 ` Ian Rogers
1 sibling, 0 replies; 25+ messages in thread
From: Ian Rogers @ 2026-06-12 5:52 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, James Clark
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, sashiko-bot, Claude Opus 4.6
On Thu, Jun 11, 2026 at 5:35 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> DSO paths from perf.data MMAP events could reference FIFOs, device
> nodes, or other special files. Opening such paths without O_NONBLOCK
> can hang perf report/script indefinitely waiting for a writer or device.
>
> Add O_NONBLOCK to all open() calls in the DSO symbol resolution paths:
> filename__read_build_id(), filename__read_debuglink(), symsrc__init(),
> do_open(), filename__decompress(), and __dso__read_symbol().
>
> O_NONBLOCK is a no-op on regular files but prevents blocking on special
> files, following the systemd "foreign file" convention. Also add missing
> O_CLOEXEC flags in symbol-minimal.c for consistency.
I think these changes are wrong and based on the bad O_NONBLOCK prompt
I fixed. I did the original addition of O_NONBLOCK and James
fixed/removed it with:
https://lore.kernel.org/linux-perf-users/20251124-james-perf-non-block-v2-1-54cdc2f13a24@linaro.org/
As we don't read from files with TEMP_FAILURE_RETRY the use of
O_NONBLOCK is going to mean slow file systems fail. The
is_regular_file tests are intended to avoid the hangs described in the
commit message.
Thanks,
Ian
> Fixes: a08cae03f430b971 ("perf tools: Allow to close dso fd in case of open failure")
> Reported-by: sashiko-bot <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/finding/6
> Cc: Jiri Olsa <jolsa@kernel.org>
> Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> tools/perf/util/dso.c | 6 +++---
> tools/perf/util/symbol-elf.c | 7 ++++---
> tools/perf/util/symbol-minimal.c | 6 +++---
> 3 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 1a2fc6d18da74d6c..dc0c8b9c63017239 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -344,7 +344,7 @@ int filename__decompress(const char *name, char *pathname,
> * descriptor to the uncompressed file.
> */
> if (!compressions[comp].is_compressed(name)) {
> - fd = open(name, O_RDONLY | O_CLOEXEC);
> + fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> *err = errno;
> if (pathname && len > 0)
> @@ -547,7 +547,7 @@ static void close_first_dso(void);
> static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
> {
> do {
> - int fd = open(name, O_RDONLY|O_CLOEXEC);
> + int fd = open(name, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
>
> if (fd >= 0)
> return fd;
> @@ -1927,7 +1927,7 @@ static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename,
> int saved_errno;
>
> nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
> - fd = open(symfs_filename, O_RDONLY | O_CLOEXEC);
> + fd = open(symfs_filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> saved_errno = errno;
> nsinfo__mountns_exit(&nsc);
> if (fd < 0) {
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index dc48e2d2763379b9..01c7b09fc82bcddb 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -886,7 +886,8 @@ static int read_build_id(const char *filename, struct build_id *bid)
> if (size < BUILD_ID_SIZE)
> goto out;
>
> - fd = open(filename, O_RDONLY | O_CLOEXEC);
> + /* O_NONBLOCK avoids hangs on FIFOs/devices from crafted perf.data paths */
> + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> goto out;
>
> @@ -1022,7 +1023,7 @@ int filename__read_debuglink(const char *filename, char *debuglink,
> if (err >= 0)
> goto out;
>
> - fd = open(filename, O_RDONLY | O_CLOEXEC);
> + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> goto out;
>
> @@ -1187,7 +1188,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
>
> type = dso__symtab_type(dso);
> } else {
> - fd = open(name, O_RDONLY | O_CLOEXEC);
> + fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0) {
> *dso__load_errno(dso) = errno;
> return -1;
> diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
> index ea2de3d50d33cf33..dc4a06b2a03ad3cb 100644
> --- a/tools/perf/util/symbol-minimal.c
> +++ b/tools/perf/util/symbol-minimal.c
> @@ -118,7 +118,7 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
> if (!is_regular_file(filename))
> return errno == 0 ? -EWOULDBLOCK : -errno;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> return -1;
>
> @@ -234,7 +234,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> char buf[BUFSIZ] __aligned(4);
> ssize_t len;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> return -1;
>
> @@ -257,7 +257,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
> enum dso_binary_type type)
> {
> - int fd = open(name, O_RDONLY);
> + int fd = open(name, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
> if (fd < 0)
> goto out_errno;
>
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-06-12 5:53 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 0:34 [PATCHES v1 00/15] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 01/15] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 02/15] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 03/15] perf symbols: Use fixed buffer in sysfs__read_build_id() for no-libelf build Arnaldo Carvalho de Melo
2026-06-12 0:47 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 04/15] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 05/15] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 06/15] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
2026-06-12 0:54 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 07/15] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
2026-06-12 2:54 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 08/15] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 09/15] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 10/15] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
2026-06-12 0:52 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 11/15] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
2026-06-12 0:34 ` [PATCH 12/15] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
2026-06-12 0:51 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 13/15] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
2026-06-12 0:58 ` sashiko-bot
2026-06-12 0:34 ` [PATCH 14/15] perf symbols: Add O_NONBLOCK to DSO open() calls for untrusted paths Arnaldo Carvalho de Melo
2026-06-12 4:57 ` sashiko-bot
2026-06-12 5:52 ` Ian Rogers
2026-06-12 0:34 ` [PATCH 15/15] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
2026-06-12 1:00 ` sashiko-bot
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.