* [PATCHES v2 00/13] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm
@ 2026-06-12 22:23 Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
` (12 more replies)
0 siblings, 13 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:23 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,
Thirteen 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 (patches 1-2):
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.
ELF note iteration (patch 3):
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 4-5):
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 6):
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 7):
hwmon_pmu__describe_items() tests fd > 0, rejecting the valid fd 0.
Undefined behavior in perf sched (patch 8):
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 9-11):
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 12):
c2c hist entries register format list entries but never unregister
them on free, leaking the list nodes.
CoreSight ETM CPU ID validation (patch 13):
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 (13):
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: 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 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 | 16 ++++++++++++++++
tools/perf/util/cs-etm.c | 9 ++++++++-
tools/perf/util/dso.c | 14 ++++++++++++--
tools/perf/util/hwmon_pmu.c | 2 +-
tools/perf/util/machine.c | 2 +-
tools/perf/util/symbol-elf.c | 3 +++
tools/perf/util/symbol-minimal.c | 5 ++++-
tools/perf/util/symbol.c | 2 +-
11 files changed, 76 insertions(+), 14 deletions(-)
Changes since v1:
- Dropped O_NONBLOCK patch per Ian Rogers' review: without
TEMP_FAILURE_RETRY, O_NONBLOCK causes slow file systems to fail; the
is_regular_file() checks are the correct mitigation.
- Dropped fixed-buffer rewrite of sysfs__read_build_id() for the
no-libelf path (type-punning fix); needs more consideration.
- Patch 11 (bpil bounds check): clear the array bit when zeroing invalid
offsets, so bpil_addr_to_offs() won't leak the heap address into
output perf.data.
- Patch 13 (cs-etm): change > INT_MAX to >= INT_MAX, preventing
max_cpu + 1 signed integer overflow in auxtrace_queues__init_nr().
Developed with AI assistance (Claude/sashiko), tagged in commits.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz
2026-06-12 22:23 [PATCHES v2 00/13] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:06 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
` (11 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id()
2026-06-12 22:23 [PATCHES v2 00/13] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:07 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
` (10 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id()
2026-06-12 22:23 [PATCHES v2 00/13] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:08 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
` (9 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:09 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 05/13] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
` (8 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 05/13] perf dso: Set error code when open() fails on uncompressed fallback path
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 06/13] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
` (7 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 06/13] perf tools: Use snprintf() for root_dir path construction
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 05/13] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
` (6 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items()
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 06/13] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:13 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
` (5 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:15 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 09/13] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
` (4 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 09/13] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
` (3 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 09/13] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:17 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 11/13] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
` (2 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 11/13] perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 13/13] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
12 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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 | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c
index d6d2c9c190f7afbf..69148197b1ef9e8b 100644
--- a/tools/perf/util/bpf-utils.c
+++ b/tools/perf/util/bpf-utils.c
@@ -264,12 +264,28 @@ 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);
+ /* clear the bit so bpil_addr_to_offs() won't reverse a zeroed address */
+ info_linear->arrays &= ~(1UL << i);
+ 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] 23+ messages in thread
* [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 11/13] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
2026-06-15 17:23 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 13/13] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
12 siblings, 1 reply; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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] 23+ messages in thread
* [PATCH 13/13] perf cs-etm: Reject CPU IDs that would overflow signed comparison
2026-06-12 22:23 [PATCHES v2 00/13] 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 22:24 ` [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
@ 2026-06-12 22:24 ` Arnaldo Carvalho de Melo
12 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-12 22:24 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..0927b0b9c06b1504 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 fit max_cpu + 1 without overflow */
+ 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] 23+ messages in thread
* Re: [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz
2026-06-12 22:24 ` [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
@ 2026-06-15 17:06 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:06 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id()
2026-06-12 22:24 ` [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-15 17:07 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:07 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id()
2026-06-12 22:24 ` [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
@ 2026-06-15 17:08 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path
2026-06-12 22:24 ` [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
@ 2026-06-15 17:09 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:09 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items()
2026-06-12 22:24 ` [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
@ 2026-06-15 17:13 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:13 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation
2026-06-12 22:24 ` [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
@ 2026-06-15 17:15 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:15 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size
2026-06-12 22:24 ` [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
@ 2026-06-15 17:17 ` Ian Rogers
0 siblings, 0 replies; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:17 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Blake Jones, Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries
2026-06-12 22:24 ` [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
@ 2026-06-15 17:23 ` Ian Rogers
2026-06-15 19:56 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 23+ messages in thread
From: Ian Rogers @ 2026-06-15 17:23 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Fri, Jun 12, 2026 at 3:25 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> 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
I don't think these are public "Closes:" links and should probably be stripped.
Thanks,
Ian
> 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 [flat|nested] 23+ messages in thread
* Re: [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries
2026-06-15 17:23 ` Ian Rogers
@ 2026-06-15 19:56 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 23+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-15 19:56 UTC (permalink / raw)
To: Ian Rogers
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, James Clark,
Jiri Olsa, Adrian Hunter, Clark Williams, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, sashiko-bot,
Claude Opus 4.6
On Mon, Jun 15, 2026 at 10:23:45AM -0700, Ian Rogers wrote:
> On Fri, Jun 12, 2026 at 3:25 PM Arnaldo Carvalho de Melo
> <acme@kernel.org> wrote:
> >
> > 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
>
> I don't think these are public "Closes:" links and should probably be stripped.
Yeap, will remove and add a memory for this not to be added again,
better to make sure that whatever is added _is_ accessible, this one
isn't :-\
- Arnaldo
> Thanks,
> Ian
>
> > 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 [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-06-15 19:57 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 22:23 [PATCHES v2 00/13] perf tools: Fix pre-existing bugs in symbols, dso, bpf, sched, c2c, hwmon, and cs-etm Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 01/13] perf symbols: Fix bswap copy-paste error for 32-bit ELF p_filesz Arnaldo Carvalho de Melo
2026-06-15 17:06 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 02/13] perf symbols: Validate p_filesz before use in filename__read_build_id() Arnaldo Carvalho de Melo
2026-06-15 17:07 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 03/13] perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id() Arnaldo Carvalho de Melo
2026-06-15 17:08 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 04/13] perf dso: Fix heap overflow in dso__get_filename() on decompressed path Arnaldo Carvalho de Melo
2026-06-15 17:09 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 05/13] perf dso: Set error code when open() fails on uncompressed fallback path Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 06/13] perf tools: Use snprintf() for root_dir path construction Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 07/13] perf hwmon: Fix fd check to accept fd 0 in hwmon_pmu__describe_items() Arnaldo Carvalho de Melo
2026-06-15 17:13 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 08/13] perf sched: Replace (void*)1 sentinel with proper runtime allocation Arnaldo Carvalho de Melo
2026-06-15 17:15 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 09/13] perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name() Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size Arnaldo Carvalho de Melo
2026-06-15 17:17 ` Ian Rogers
2026-06-12 22:24 ` [PATCH 11/13] perf bpf: Bounds-check array offsets in bpil_offs_to_addr() Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 12/13] perf c2c: Free format list entries when releasing c2c hist entries Arnaldo Carvalho de Melo
2026-06-15 17:23 ` Ian Rogers
2026-06-15 19:56 ` Arnaldo Carvalho de Melo
2026-06-12 22:24 ` [PATCH 13/13] perf cs-etm: Reject CPU IDs that would overflow signed comparison Arnaldo Carvalho de Melo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox