Commit Graph

54515 Commits

Author SHA1 Message Date
Ian Rogers
cb45ede21d perf python: Fix count_values memory leak in pyrf_evsel__read
In pyrf_evsel__read, if PyArg_ParseTuple fails, the allocated count_values
is leaked. Move the allocation of count_values after the PyArg_ParseTuple
call to prevent the memory leak.

Fixes: 739621f657 ("perf python: Add evsel read method")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 22:02:41 -07:00
Ian Rogers
b9514a9a13 perf python: Fix MetricGroup return type in perf.pyi
The metrics() function can return a dictionary where the value is either
a string or a list of strings, so the type signature in the stub file
should be Union[str, List[str]].

Fixes: 430da3cd03b4 ("perf python: Add perf.pyi stubs file")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 22:02:41 -07:00
Ian Rogers
b3d7c6c1a9 perf python: Add thread and PMU uninitialized checks
Add CHECK_INITIALIZED checks to the thread attribute getters
(get_pid, get_tid, get_ppid) to prevent crashes if they are accessed
before being properly initialized.

Fixes: 3b96bf7af60d ("perf python: Add python session abstraction wrapping perf's session")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 22:02:38 -07:00
Ian Rogers
b365402cd5 perf python: Zero initialize perf_data in pyrf_data__init
Replace path clearing with memset so the entire struct is zeroed,
preventing uninitialized fields from causing errors later.

Fixes: 4cd0142f7dec ("perf python: Add wrapper for perf_data file abstraction")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
0b274050c4 perf python: Validate attribute setters in pyrf_evsel
If val is NULL when setting an attribute, PyErr_SetString should be
called as deleting the attribute isn't supported. In addition, ensure
PyErr_Occurred is checked before setting the attribute to avoid setting
a garbage value.

Fixes: 877108e42b ("perf tools: Initial python binding")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
9a142beb1e perf python: Validate CPU and thread maps in pyrf_evsel__open
Add explicit Py_TYPE checks to ensure the arguments passed are
actually of the correct pyrf_thread_map and pyrf_cpu_map types.

Fixes: 877108e42b ("perf tools: Initial python binding")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
612aca22a9 perf python: Check counts_values size in set_values
The set_values function incorrectly assumed the list contained exactly
5 elements. Add a check to prevent out-of-bounds access.

Fixes: 877108e42b ("perf tools: Initial python binding")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
44e82c4d2f perf test: Fix skiplist leak in cmd_test
Fix a memory leak in cmd_test() where skiplist was not freed on
exit paths.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: 2ae828786c ("perf test: Allow skipping tests")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
54ba44db4d perf synthetic-events: Fix uninitialized pthread_join
In perf_event__synthesize_threads(), fix an uninitialized pthread_join()
call when thread creation fails by only joining the successfully
created threads.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: 340b47f510 ("perf top: Implement multithreading for perf_event__synthesize_threads")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
38d778acbe perf python: Fix memory leak in pyrf_evlist__get_pollfd
Fix a Python list object leak in pyrf_evlist__get_pollfd() by adding
a missing Py_DECREF on the error exit path.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: 877108e42b ("perf tools: Initial python binding")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:11 -07:00
Ian Rogers
08e96e3c73 perf tools: Fix sb_evlist leaks in top and record
Fix a memory leak in cmd_top() where top.sb_evlist was not freed if
evlist__add_bpf_sb_event() fails. Note that evlist__start_sb_thread() and
evlist__stop_sb_thread() take ownership of the evlist and free it, so
we must only free it if we fail before starting the thread. Also set
top.sb_evlist to NULL to prevent use-after-free bugs.

Apply the same fix to builtin-record.c to avoid leaking rec->sb_evlist
and calling pthread_join on uninitialized threads in the error path.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: b38d85ef49 ("perf bpf: Decouple creating the evlist from adding the SB event")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:10 -07:00
Ian Rogers
340641a4b5 perf stat: Fix evsel_list leak in cmd_stat
Fix a memory leak in cmd_stat() where evsel_list is leaked if an error
occurs while opening the output file.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: 361c99a661 ("perf evsel: Introduce perf_evlist")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:10 -07:00
Ian Rogers
d4171c7740 perf script: Fix metric_evlist leak in script_find_metrics
Fix a memory leak in script_find_metrics() where metric_evlist is leaked
when returning early on error paths.

Assisted-by: Antigravity:gemini-3.1-pro
Fixes: 3622990efa ("perf script: Change metric format to use json metrics")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-09 21:58:10 -07:00
Aaron Tomlin
bf10e6ee2a perf sched latency: Add histogram and time interval options
While 'perf sched latency' reports task runtime and delay statistics
(average and maximum delay), it does not provide a visual representation
of how task wait times are distributed across latency ranges between
snapshots (start and finish of the analysis window).

The --histogram option collects CPU wait latencies (time between when
a task becomes runnable and when it gets scheduled onto a CPU) into 22
latency buckets, displaying an ASCII bar chart distribution.

The --hist-mode option configures the bucketing scheme:
  - log (default). Logarithmic latency buckets ranging from
    sub-microsecond (< 1 us) up to >= 1.05 seconds

  - linear. Equal-width linear latency buckets
    (i.e., 100 us steps up to >= 2.1 ms)

The --time option allows filtering trace event processing to a
specific time interval [start,stop].

Example histogram output excerpt:

    ❯ sudo perf sched latency --histogram --CPU 0

     CPU Wait Latency Distribution Histogram (between snapshots) (total samples: 36114)
     -------------------------------------------------------------------
      Latency Range    |      Count |    Pct | Histogram Graph
     -------------------------------------------------------------------
      < 1 us           |         17 |   0.0% | #
      2 - 4 us         |        673 |   1.9% | #
      4 - 8 us         |       6237 |  17.3% | ######
      8 - 16 us        |       3224 |   8.9% | ###
      16 - 32 us       |       1388 |   3.8% | #
      32 - 64 us       |        709 |   2.0% | #
      64 - 128 us      |        690 |   1.9% | #
      128 - 256 us     |        789 |   2.2% | #
      256 - 512 us     |        541 |   1.5% | #
      512 - 1024 us    |       2256 |   6.2% | ##
      1 - 2 ms         |       3577 |   9.9% | ###
      2 - 4 ms         |      13259 |  36.7% | ##############
      4 - 8 ms         |       2523 |   7.0% | ##
      8 - 16 ms        |        222 |   0.6% | #
      16 - 32 ms       |         10 |   0.0% | #
      >= 1.05 s        |          3 |   0.0% | #
     -------------------------------------------------------------------

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 10:56:23 -07:00
Aaron Tomlin
19ea850c02 perf sched latency: Auto-scale latency and runtime display units
Currently, 'perf sched latency' displays task runtime and delay values
exclusively in milliseconds (ms). This can be hard to read when
latencies are very small (in the microsecond or nanosecond range) or
unusually large (seconds).

Introduce auto-scaling for latency and runtime display columns. Values
are dynamically scaled and output with the most appropriate unit:
nanoseconds (ns), microseconds (us), milliseconds (ms), or seconds (s).

Additionally, rename column headers from "Runtime ms", "Avg delay ms",
and "Max delay ms" to "Runtime", "Avg delay", and "Max delay"
respectively, adjust spacing to maintain column alignment and stripe
redundant prefix strings from each row's format string to produce a
clean, tabular output.

For illustrative purposes, a comparison of the latency table header
before and after this change is shown below:

Before:
 -------------------------------------------------------------------------------------------------------------------------------------------
  Task                  |   Runtime ms  |  Count   | Avg delay ms    | Max delay ms    | Max delay start           | Max delay end          |
 -------------------------------------------------------------------------------------------------------------------------------------------
  kworker/2:2-mm_:154757 |      0.033 ms |        1 | avg:   0.829 ms | max:   0.829 ms | max start: 169486.543205 s | max end: 169486.544034 s

After:
 ------------------------------------------------------------------------------------------------------------------------------------------
  Task                    |    Runtime     |  Count   |    Avg delay    |    Max delay    |      Max delay start  |     Max delay end     |
 ------------------------------------------------------------------------------------------------------------------------------------------
  kworker/2:2-mm_:154757  |      32.873 us |        1 |      829.347 us |      829.347 us |       169486.543205 s |       169486.544034 s |

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 10:56:23 -07:00
Aaron Tomlin
44f8dd1ee1 perf sched: Handle missing trace samples in pipe mode
For pipe mode streams, event attributes are received dynamically during
event processing, meaning session->evlist is not populated prior to
perf_session__process_events(). To handle pipe input correctly:
  - Register the missing .attr, .tracing_data, .build_id, and .feature
    callbacks in cmd_sched()

  - Promote the handlers array to file-scope (latency_handlers[]) and
    dynamically assign matching tracepoint handlers
    (or process_sched_ignore) inside
    perf_sched__process_tracepoint_sample() when evsel->handler is NULL;
    replace process_sched_wakeup_ignore() with process_sched_ignore()

  - Perform the trace check post-processing when handling pipe data

Fixes: 27295592c2 ("perf session: Share the common trace sample_check routine as perf_session__has_traces")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 10:56:22 -07:00
Aaron Tomlin
4a81d59a9d perf sched: Suppress latency table output when trace samples are missing
When 'perf sched latency' is executed on a perf.data file that lacks
tracepoint samples (i.e., a file recorded without the -R flag or
containing only non-tracepoint events), perf_session__has_traces()
correctly outputs an error message. However, perf_sched__read_events()
subsequently falls through and returns 0 (success).

Consequently, caller functions such as perf_sched__lat() assume event
processing succeeded and proceed to render empty latency header tables
and total summary statistics.

Fix this behaviour by ensuring perf_sched__read_events() aborts early and
returns a suitable error code when perf_session__has_traces() evaluates
to false.

Additionally, validate thread__get_runtime() against NULL in
map_switch_event() to prevent potential null-pointer dereferences.

Fixes: 27295592c2 ("perf session: Share the common trace sample_check routine as perf_session__has_traces")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 10:56:22 -07:00
Ian Rogers
006a6f0f6e perf synthetic-events: Fix bounds and union member access in mmap2 build_id synthesis
Modify bounds and union member access in mmap2 build_id synthesis. Bound
max_filename_len against the minimum of filename array capacity and the
outer union stack layout minus sample ID trailers. This prevents both
-E2BIG overruns and _FORTIFY_SOURCE array bounds aborts on strlcpy even
if the enclosing union expands.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Ian Rogers
b97c535768 perf synthetic-events: Fix bounds, stale state, and misc flags in kernel module synthesis
Clamp long DSO names to mmap/mmap2 filename boundaries accounting for
sample ID headers to prevent buffer overruns in
perf_event__synthesize_modules_maps_cb(). Explicitly clear misc flags and
union padding to prevent stale Build-ID state from leaking between module
synthesis events, and cast event buffer pointers to avoid _FORTIFY_SOURCE
array bounds aborts when zeroing padding trailers.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Ian Rogers
093f58e60e perf synthetic-events: Fix stack buffer overflow and bounds in cgroup synthesis
Fix a pre-existing stack buffer overflow bug in
perf_event__synthesize_cgroup() where an in-place null padding loop wrote
bytes past the end of the cgrp_root stack array buffer during cgroup tree
traversal. Eliminate in-place path mutation, use PERF_ALIGN for path_len,
clamp raw_path_len to prevent sample ID header trailer overruns, and use
strlcpy with combined zero padding for alignment and sample ID headers.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Ian Rogers
505a498a37 perf synthetic-events: Fix line synchronization, bounds, and truncation bugs in proc maps reader
Fix critical logic and boundary bugs in read_proc_maps_line() and caller.
Ensure any mid-line hex/dec/char parsing failure invokes io__drain_line()
safely, using a do-while loop to read and discard remaining characters
until a newline or EOF is reached. Clamp pathname extraction size to
account for trailing sample ID headers, use standard '//toolong' fallback
literal for over-length pathnames, emit timeout flags for truncated entries
securely via goto out;, and cast event buffer pointers to avoid
_FORTIFY_SOURCE array bounds aborts across synthesis handlers.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Ian Rogers
e46a9b8150 perf find-map: Remove PATH_MAX 128-byte stack array restriction
Use getline() to dynamically allocate the required line buffer for maps
parsing, guaranteeing bounds safety and avoiding compiler warnings
by evaluating the return value in the loop condition directly.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Tanushree Shah
43a163494f perf trace-event: Fix infinite loop in skip()
skip() ignores do_read()'s return value and unconditionally
subtracts the requested chunk size from 'size' on every iteration.
This was previously bounded by size being 'int': a maliciously
large 64-bit value was truncated on assignment, capping the loop
early by accident.

Now that size is size_t, a crafted file supplying a very large
size causes skip() to keep requesting BUFSIZ-sized reads and
subtracting BUFSIZ from size regardless of whether do_read()
actually succeeds, spinning indefinitely even after EOF or a read
error.

Check do_read()'s return value and break out of the loop on
failure or EOF, so forward progress is only counted when a read
actually succeeds.

Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Tanushree Shah
c291f143cc perf trace-event: Fix heap overflows in read_ftrace_printk()/read_saved_cmdline()
Both functions read an attacker-controlled size directly from the
input file and pass size + 1 to malloc() before reading size bytes
into the result:

read_ftrace_printk(): size is an unsigned int from read4(). When
size == UINT_MAX, size + 1 overflows to 0, so malloc(0) returns a
minimal allocation while size itself remains UINT_MAX.

read_saved_cmdline(): size is an unsigned long long from read8().
When size == ULLONG_MAX, size + 1 overflows to 0 the same way.

In both cases, do_read(buf, size) then attempts to read the full,
unwrapped size into the tiny allocated buffer, a heap buffer
overflow.

This was previously masked by do_read()'s size parameter being
'int': passing these values truncated them, which the read()
syscall's own boundary checks rejected before any data was read.
Fixing that truncation (widening do_read() to size_t) is correct
on its own, but it removes this accidental protection and exposes
the pre-existing missing bounds check in both functions.

Reject the one value that causes the overflow before it's used, in
each function.

Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Tanushree Shah
6c07d49ef3 perf trace-event: Avoid double free and leak in trace_event__cleanup()/trace_event__init()
trace_event__cleanup() frees t->pevent but never clears the
pointer. It can be called twice on the same trace_event: once
from trace_report()'s error path, and again from
perf_session__delete() during session teardown, resulting in a
double free / use-after-free.

Separately, trace_event__init() overwrites t->pevent/t->plugin_list
without releasing any existing handle, leaking memory if it's
called more than once on the same struct. eg. via a perf.data
file with multiple PERF_RECORD_HEADER_TRACING_DATA headers.

Guard against re-entry by returning early if t->pevent is already
NULL, and clear it after cleanup so a repeat call is a safe no-op.
Call trace_event__cleanup() at the start of trace_event__init(),
so a repeated init releases any existing handle before allocating
a new one.

Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:43:36 -07:00
Tanushree Shah
c108c1391b perf trace-event: Fix integer truncation in do_read() and skip()
The do_read() and skip() functions use 'int' for size parameters,
truncating 64-bit sizes from callers. This causes two issues:

1. Uninitialized memory dump: do_read() reads fewer bytes than
   allocated, leaving uninitialized heap memory that gets written
   to output files.

2. Out-of-bounds read: Parsing functions process the full 64-bit
   size while only partial data was read into the buffer.

Change do_read(), __do_read(), and skip() to use size_t for size
parameters and ssize_t for return values (where applicable), matching
read()/write() system calls.
Update callers to use ssize_t for storing return values.

Fixes: 4a31e56599 ("perf tools: Get rid of read_or_die() in trace-event-read.c")
Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-07 09:40:15 -07:00
Tanushree Shah
1121a7af18 perf trace-event: Fix buffer overflow in read_string()
read_string() writes into buf[BUFSIZ] one byte at a time without
checking 'size' against the buffer bound before each write. A
string longer than BUFSIZ in the input overflows the stack buffer.

Add a bounds check before each write to prevent overflow. On
overflow the function returns NULL, matching its other error paths.

Fixes: 9215545e99 ("perf: Convert perf tracing data into a tracing_data event")
Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-06 09:13:15 -07:00
Arnaldo Carvalho de Melo
6d421f609b perf c2c: Clean up registered formats on c2c_hists__init() and c2c_hists__reinit() failure
When c2c_hists__init() or c2c_hists__reinit() calls hpp_list__parse()
and it fails partway through, format structures registered via
perf_hpp_list__column_register() and perf_hpp_list__register_sort_field()
are left on the hpp_list.

In c2c_hists__init(), only one of the callers, c2c_he__alloc_hists(),
handled this with perf_hpp__reset_output_field(), while perf_c2c_report()
did not, leaking the partially registered entries.

In c2c_hists__reinit(), neither perf_c2c_report() nor resort_cl_cb()
clean up on failure.

Fix by adding cleanup inside both functions themselves, so all callers
are protected, and remove the now redundant reset in c2c_he__alloc_hists().

Fixes: 78b2754378 ("perf c2c report: Add sample processing")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Assisted-by: Opencode:mimo-v2.5-free
Assisted-by: Opencode:DeepSeek-V4-Flash-free
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 21:50:45 -07:00
Arnaldo Carvalho de Melo
f53f5c2437 perf c2c: Fix error masking, OOM, and unchecked caller errors in hpp_list__parse()
hpp_list__parse() has three bugs:

1. The PARSE_LIST macro resets ret = 0 at the start of each invocation,
   so an error from output parsing is silently overwritten when the sort
   parsing block runs.  The function returns success with partially
   initialized state.

2. When the caller passes a non-NULL output_ or sort_ string, but
   strdup() returns NULL due to OOM, NULL is passed to PARSE_LIST which
   treats it as empty input (the "if (!_list) break" branch).  No error
   is returned.

3. When the called _fn function fails and returns something other than
   -ESRCH or -EINVAL (-ENOMEM, for instance) it was not bailing out of
   the strtok loop.

Fix them by checking strdup() return values before proceeding and adding
a cleanup label so that ret from each PARSE_LIST call is checked before
the next runs, preserving the first error.

The early exits now skip perf_hpp__setup_output_field(), which means
c2c_hists__reinit() can return a non-zero value in cases that previously
always succeeded silently.  Both callers discarded its return:
resort_cl_cb() continued into hists__collapse_resort() on a broken list,
and perf_c2c__report() proceeded with uninitialised hists.  Fix the full
chain: check and propagate the error in resort_cl_cb() -- hists__iterate_cb()
already stops iteration and returns the callback error -- and check both
c2c_hists__reinit() and hists__iterate_cb() in perf_c2c__report().

Also turn PARSE_LIST into a function, using a switch to catch other
errors, converting the called functions to return an appropriate errno
instead of -1 on failure.

Also make the two callers that iterate sort_dimension__add() and
output_field_add() handle the newly propagated errors: setup_sort_list()
and setup_output_list() only checked for -EINVAL and -ESRCH, so an
-ENOMEM from a failed allocation was silently overwritten by the next
loop iteration.  Break out of the loop and propagate any other error.

The hpp_list__parse() fixes were developed with AI assistance from
Claude:claude-sonnet-4.6, and the setup_sort_list()/setup_output_list()
caller fixes with AI assistance from Opencode:mimo-v2.5-free and
Opencode:DeepSeek-V4-Flash-free.

Fixes: 2d388bd0c9 ("perf c2c report: Add stdio output support")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Assisted-by: Claude:claude-sonnet-4.6
Assisted-by: Opencode:mimo-v2.5-free
Assisted-by: Opencode:DeepSeek-V4-Flash-free
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 21:50:45 -07:00
Arnaldo Carvalho de Melo
fe3ab00d55 perf libbfd: Fix memory leaks and NULL fclose in BPF disassembly
symbol__disassemble_bpf_libbfd() has four resource management bugs:

1. free(prog_linfo) leaks internal arrays.  bpf_prog_linfo contains
   raw_linfo, raw_jited_linfo, nr_jited_linfo_per_func, and
   jited_linfo_func_idx pointers that are only freed by the proper
   destructor bpf_prog_linfo__free().

2. open_memstream(&buf, &buf_size) allocates a dynamic buffer that the
   caller must free after fclose().  The function calls fclose(s) but
   never free(buf), leaking the stream buffer on every call.

3. args->line = strdup(srcline) is immediately consumed by
   disasm_line__new(args) which internally calls strdup(args->line)
   again via annotation_line__init().  The first strdup result is then
   overwritten by args->line = buf + prev_buf_size without being freed.

4. If open_memstream() fails, the error path jumps to 'out:' which
   calls fclose(s) with s == NULL — undefined behavior.

Fix by using bpf_prog_linfo__free(), initializing buf to NULL, adding
free(buf) after fclose(s), guarding fclose() against NULL, and removing
the redundant strdup since annotation_line__init() makes its own copy.

Fixes: 6987561c9e ("perf annotate: Enable annotation of BPF programs")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 11:20:03 -07:00
Arnaldo Carvalho de Melo
38ba525335 perf bpf: Add PROG_TAGS to required arrays in __bpf_event__print_bpf_prog_info()
synthesize_bpf_prog_name() unconditionally dereferences prog_tags[sub_id]
(line: u8 (*prog_tags)[BPF_TAG_SIZE] = (void *)(uintptr_t)(info->prog_tags))
but __bpf_event__print_bpf_prog_info() only requires JITED_KSYMS and
JITED_FUNC_LENS in its required_arrays bitmask.

If a crafted perf.data has the PROG_TAGS bit cleared (or the array was
invalidated by bpil_offs_to_addr() bounds checking), info->prog_tags
contains either zero or a raw file offset.  Dereferencing it causes a
NULL pointer dereference or an arbitrary memory read.

Add PERF_BPIL_PROG_TAGS to required_arrays so the function returns early
when prog_tags was not present or failed validation.

Fixes: f8dfeae009 ("perf bpf: Show more BPF program info in print_bpf_prog_info()")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 11:20:02 -07:00
Arnaldo Carvalho de Melo
60f2f5b765 perf header: Use write lock when translating BPF prog info pointers
write_bpf_prog_info() holds a read lock while temporarily mutating
info_linear via bpil_addr_to_offs()/bpil_offs_to_addr().  Between these
two calls, the pointers in info_linear contain file offsets instead of
heap addresses.  Concurrent readers holding the same read lock see the
file offsets and dereference them as pointers.

Use down_write()/up_write() instead of down_read()/up_read() to exclude
concurrent readers during the addr-to-offset-to-addr translation window.

Fixes: 63ac7968a1fb ("perf bpf: Save bpf_prog_info information as headers to perf.data")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 11:20:02 -07:00
Arnaldo Carvalho de Melo
01765b456f perf libbfd: Validate BPF prog info arrays before pointer cast
symbol__disassemble_bpf_libbfd() casts info_linear->info.jited_prog_insns
and info_linear->info.jited_ksyms to pointers without checking whether
bpil_offs_to_addr() actually converted the file offsets.  A crafted
perf.data with PERF_BPIL_* bits unset but non-zero counts causes raw
file offsets to be dereferenced as pointers.

Add bitmask checks for PERF_BPIL_JITED_INSNS and PERF_BPIL_JITED_KSYMS
before the casts, matching the validation added to bpf-event.c call
sites.

Fixes: 6987561c9e ("perf annotate: Enable annotation of BPF programs")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 11:20:02 -07:00
Aaron Tomlin
9dd7c82d46 perf trace: Format fields with hex specifiers in print_fmt as hexadecimal
Currently, when a probe event is added using perf probe --add with a
hexadecimal type cast (e.g., var:x64 and var:x32), the kernel traceprobe
subsystem sets the field type to "u64" in the event's format file, yet
generates a print format specifier of "var=0x%Lx" or "0x%x".

By default, perf trace uses its internal beautifiers which only inspect
field->type and field->flags. Because traceprobe events declare
primitive integer field types ("u64") without a C pointer asterisk
(i.e., "*"), perf trace defaults to printing the field's value as a
decimal unsigned long ("%ld"), ignoring the hexadecimal intent.

Introduce field_has_hex_fmt() to inspect the tracepoint's print_fmt
format string. If a field's print format assignment uses hexadecimal
specifiers (i.e., "=0x", "=%#", or "=%p"), assign SCA_PTR formatting so
perf trace displays the value in hexadecimal by default without
requiring --libtraceevent. For example:

    ❯ sudo ./perf probe --add 'enqueue_task_fair rq=rq:x64 p=p:x64 flags=flags:x32'
    Added new event:
      probe:enqueue_task_fair (on enqueue_task_fair with rq=rq:x64 p=p:x64 flags=flags:x32)

    You can now use it in all perf tools, such as:

            perf record -e probe:enqueue_task_fair -aR sleep 1

    ❯ sudo ./perf trace --show-cpu --event probe:enqueue_task_fair --max-event 3
         0.000 [000] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac632233180, p: 0xffff8ac2c1240000, flags: 0x100009)
         0.006 [004] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac632433180, p: 0xffff8ac624cf8000, flags: 0x9)
         0.069 [001] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac6322b3180, p: 0xffff8ac4c4212c40, flags: 0x9)

Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-05 11:20:02 -07:00
Chun-Tse Shao
00ab8057cc perf vendor events intel: Fix Novalake CPUID regex in mapfile.csv
Based on offline discussion with Intel in
lore.kernel.org/20260715211144.3144895-1-ctshao@google.com, we decided
to drop the leading zero from Nova Lake models 0x01 and 0x03 in
mapfile.csv to match single-digit model numbers without zero padding
(GenuineIntel-18-[13]).

The updated mapfile entry was published in:
github.com/intel/perfmon/commit/00167baed45ac3b2708e89dbf1b9ce4769e9d115

Signed-off-by: Chun-Tse Shao <ctshao@google.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-04 10:08:48 -07:00
Arnaldo Carvalho de Melo
d67241d43b perf arm-spe: Reject zero nr_cpu in metadata to prevent division by zero
arm_spe__alloc_metadata() reads nr_cpu from the auxtrace_info priv
array without validation.  When a crafted perf.data provides nr_cpu=0,
the per_cpu_sz calculation divides by zero:

  per_cpu_sz = (metadata_size - (hdr_sz * sizeof(u64))) / (*nr_cpu);

Reject nr_cpu <= 0 early, before the division.  The caller already
treats NULL return with metadata_ver != 1 as a parse failure.

Fixes: 7842a4b6ff ("perf arm-spe: Support metadata version 2")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 12:43:10 -07:00
Arnaldo Carvalho de Melo
b9fb822595 perf intel-bts: Fix off-by-one in auxtrace_info minimum size check
Same pattern as the Intel PT fix: min_sz is set to
sizeof(u64) * INTEL_BTS_SNAPSHOT_MODE, but the code accesses
auxtrace_info->priv[INTEL_BTS_SNAPSHOT_MODE], which requires at least
INTEL_BTS_SNAPSHOT_MODE + 1 elements.

Use (INTEL_BTS_SNAPSHOT_MODE + 1) to ensure the highest accessed index
is within bounds.

Fixes: d0170af700 ("perf tools: Add Intel BTS support")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 12:43:05 -07:00
Arnaldo Carvalho de Melo
c4362d5e1a perf intel-pt: Fix off-by-one in auxtrace_info minimum size check
min_sz is set to sizeof(u64) * INTEL_PT_PER_CPU_MMAPS, but the code
accesses auxtrace_info->priv[INTEL_PT_PER_CPU_MMAPS], which requires
at least INTEL_PT_PER_CPU_MMAPS + 1 elements.  A file with exactly
min_sz bytes of priv data passes the size check but the access reads
one u64 past the validated region.

Use (INTEL_PT_PER_CPU_MMAPS + 1) to ensure the highest accessed index
is within bounds.

Fixes: 90e457f7be ("perf tools: Add Intel PT support")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 12:43:01 -07:00
Arnaldo Carvalho de Melo
96fcc9ea5f perf auxtrace: Fix queue grow overflow and old array leak
auxtrace_queues__grow() has two bugs:

1. When idx is UINT_MAX, the caller passes new_nr_queues = idx + 1 = 0.
   The function skips growing (since any nr_queues >= 0), returns
   success, and the caller accesses queue_array[UINT_MAX] — an OOB
   heap write.  Fix by rejecting new_nr_queues == 0 up front.

2. The function allocates a new queue_array via calloc and copies
   elements from the old array, but never frees the old array.  Fix
   by saving the old pointer and freeing it after the copy.

Fixes: e502789302 ("perf auxtrace: Add helpers for queuing AUX area tracing data")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 12:42:53 -07:00
Arnaldo Carvalho de Melo
ab9c84d1cd perf thread-stack: Fix heap buffer overflow on branch stack wrap copy
thread_stack__br_sample() copies the wrap-around portion of the branch
stack ring buffer with:

  nr = min(ts->br_stack_pos, sz);
  memcpy(be, &src->entries[0], bsz * ts->br_stack_pos);

'nr' is correctly bounded to min(br_stack_pos, sz) but the memcpy uses
the unbounded ts->br_stack_pos directly.  When br_stack_pos exceeds
the remaining destination space 'sz', this writes past the destination
buffer.

Use 'nr' (the bounded value) in the memcpy size, matching the pattern
of the first memcpy in the same function.

Fixes: 86d67180b9 ("perf thread-stack: Add branch stack support")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 12:42:49 -07:00
Pu Hu
5a3e6136e3 perf pmu-events: Fix typo in idle-cycles-frontend description
The brief description of the idle-cycles-frontend legacy hardware event
refers to its alias as "stalled-cycles-fronted", but there is no such
event. The correct event name is "stalled-cycles-frontend".

This typo is visible in the output of "perf list", for example:

  idle-cycles-frontend
       [Stalled cycles during issue [This event is an alias of
        stalled-cycles-fronted]. Unit: armv8_pmuv3]

Fix the spelling so that the description points to the valid event name.

Signed-off-by: Pu Hu <hupu@transsion.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 11:08:17 -07:00
Michail Tatas
9d393ca644 perf ftrace: Fix leak in parse_filter_event
strsep() advances the pointer given to it. After the loop s is
either NULL (on success) or points mid buffer (early exit if malloc
fails) so the original buffer is never freed properly.
Fix by adding a tmp pointer for use by strsep and free the original
pointer

Signed-off-by: Michail Tatas <michail.tatas@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-03 10:39:13 -07:00
Namhyung Kim
dbd2505061 perf build: Fix a build error on 32-bit x86
The commit d7507a94a0 ("KVM: SVM: Treat exit_code as an unsigned
64-bit value through all of KVM") added "ull" suffix to SVM exit codes
and it makes the 32-bit build fail like below.

  In file included from util/kvm-stat-arch/kvm-stat-x86.c:4:
  util/kvm-stat-arch/../../../arch/x86/include/uapi/asm/svm.h:137:32:
             error: conversion from 'long long unsigned int' to 'long unsigned int' changes
                    value from '18446744073709551615' to '4294967295' [-Werror=overflow]
    137 | #define SVM_EXIT_ERR           -1ull
        |                                ^
  util/kvm-stat-arch/../kvm-stat.h:131:17: note: in definition of macro 'define_exit_reasons_table'
    131 |                 symbols, { -1, NULL }                   \
        |                 ^~~~~~~
  util/kvm-stat-arch/../../../arch/x86/include/uapi/asm/svm.h:249:11: note: in expansion of macro 'SVM_EXIT_ERR'
    249 |         { SVM_EXIT_ERR,         "invalid_guest_state" }
        |           ^~~~~~~~~~~~
  util/kvm-stat-arch/kvm-stat-x86.c:12:45: note: in expansion of macro 'SVM_EXIT_REASONS'
     12 | define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
        |                                             ^~~~~~~~~~~~~~~~

As the exit_code was unsigned long, the compiler complained about the
truncation.  Let's convert it to u64 to suppress the error.

Fixes: fac520e43a ("tools headers: Sync KVM headers with the kernel sources")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-02 09:45:18 -07:00
Zhanpeng Zhang
3a13ed3111 perf symbols: Skip dynamic symbols with invalid section indexes
RISC-V post-link processing can remove relocation sections from the final
vmlinux while some .dynsym entries retain stale section indexes. perf
aborts the whole ELF symbol load when elf_getscn() rejects one of them,
discarding otherwise valid .symtab symbols.

Skip only dynamic symbols whose normal section index is outside the final
section table. Keep the existing error path for .symtab, reserved indexes,
and other libelf failures.

On an affected system, the vmlinux symtab matches kallsyms test changes
from Skip to Ok. [unknown] rows in the same perf.data change from 41 to 0.

Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-08-02 09:44:58 -07:00
Arnaldo Carvalho de Melo
d04ef71492 perf machine: Check snprintf truncation for guest kallsyms path
machines__create_guest_kernel_maps() builds the guest kallsyms path
with snprintf() without checking the return value.  A truncated path
could pass the access() check if a prefix directory happens to contain
a file named "kallsyms", leading to the wrong file being used for
symbol resolution.

Check for truncation and skip the directory.

Fixes: a1645ce12a ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:42:28 -07:00
Arnaldo Carvalho de Melo
f53bf58dcd perf machine: Free scandir entries in guest kernel map creation
machines__create_guest_kernel_maps() calls scandir() which allocates
both the namelist array and each individual dirent entry.  The code
frees the namelist array but not the individual entries, leaking memory
proportional to the number of directories under guestmount.

Free each namelist[i] after it is no longer needed.

Fixes: a1645ce12a ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:42:17 -07:00
Arnaldo Carvalho de Melo
29ec46e43f perf machine: Reset errno before strtol in guest kernel map creation
machines__create_guest_kernel_maps() checks errno == ERANGE after
strtol() to detect overflow, but does not clear errno first.  A stale
ERANGE from an earlier library call (e.g. scandir internals) causes
valid numeric directory names to be incorrectly skipped.

Set errno = 0 before strtol() so only the current conversion can
trigger the ERANGE check.

Fixes: a1645ce12a ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:42:07 -07:00
Arnaldo Carvalho de Melo
b687e1a418 perf machine: Don't abort guest map creation on first inaccessible dir
machines__create_guest_kernel_maps() jumps to the failure label when one
guest directory's kallsyms file fails access(), skipping all remaining
valid guest directories.  An inaccessible directory is not fatal — other
guests may still be reachable.

Replace 'goto failure' with 'continue' so the loop processes all
directories, and remove the now-unreferenced failure label.

Fixes: a1645ce12a ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:41:56 -07:00
Arnaldo Carvalho de Melo
cc6abe0012 perf machine: Check snprintf truncation in machines__findnew()
The guestmount path is built with snprintf() into a PATH_MAX buffer
without checking the return value.  If symbol_conf.guestmount is long
enough to cause truncation, the truncated path could match a different
directory, causing the wrong guest to be associated with the pid.

Check for truncation and bail out early.

Fixes: a1645ce12a ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:41:41 -07:00
Arnaldo Carvalho de Melo
e27b96d0a3 perf machine: Guard against NULL strlist in machines__findnew()
The static 'seen' strlist caches guestmount paths that have already
been reported as inaccessible, to avoid repeating the error message.
If strlist__new() fails (OOM), 'seen' stays NULL and the next call
dereferences it via strlist__has_entry() and strlist__add().

Guard both calls so that on allocation failure the error message is
still printed (just not deduplicated) instead of crashing.

Fixes: c80c3c2690 ("perf kvm: Limit repetitive guestmount message to once per directory")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-31 16:41:38 -07:00