Re: [PATCH v7 32/59] perf arm-cs-trace-disasm: Port arm-cs-trace-disasm to use python module

sashiko-bot
2026-04-25T23:25:55Z

Sashiko AI review found 2 potential issue(s):
- [High] Event filtering logic drops all samples due to incorrect stringification of evsel.
- [High] Relative 'vmlinux' path fallback allows arbitrary code execution from untrusted directories.
--

commit bfb5fa4502593496d0bc26784e43f473bbcc607c
Author: Ian Rogers <irogers@google.com>

perf arm-cs-trace-disasm: Port arm-cs-trace-disasm to use python module

This commit ports the arm-cs-trace-disasm script to use the perf python
module directly. This avoids creating intermediate dictionaries for all
event fields, improving performance. The testing script is also updated
to use the ported script.

> diff --git a/tools/perf/python/arm-cs-trace-disasm.py b/tools/perf/python/arm-cs-trace-disasm.py
> new file mode 100755
> index 000000000000..92c97cca6f66
> --- /dev/null
> +++ b/tools/perf/python/arm-cs-trace-disasm.py
> @@ -0,0 +1,338 @@
[ ... ]
> +KVER = platform.release()
> +VMLINUX_PATHS = [
> + f"/usr/lib/debug/boot/vmlinux-{KVER}.debug",
> + f"/usr/lib/debug/lib/modules/{KVER}/vmlinux",
> + f"/lib/modules/{KVER}/build/vmlinux",
> + f"/usr/lib/debug/boot/vmlinux-{KVER}",
> + f"/boot/vmlinux-{KVER}",
> + "/boot/vmlinux",
> + "vmlinux"
> +]

Is there a risk that checking for "vmlinux" as a relative path could load an
untrusted binary?

If this script is executed from a world-writable directory like /tmp, it
might find and use an attacker-controlled vmlinux file placed there.

Because this binary is subsequently passed to objdump via
subprocess.check_output(), parsing a maliciously crafted binary could
trigger vulnerabilities and lead to arbitrary code execution.

[ ... ]
> + def process_event(self, sample: perf.sample_event) -> None:
[ ... ]
> + ev_name = str(sample.evsel)
> + if self.options.verbose:
> + print(f"Event type: {ev_name}")
> + print_sample(sample)
> +
> + dso = sample.dso or '[unknown]'
> + symbol = sample.symbol or '[unknown]'
> + dso_bid = sample.dso_bid or '[unknown]'
> + dso_start = sample.map_start
> + dso_end = sample.map_end
> + map_pgoff = sample.map_pgoff or 0
> +
> + comm = "[unknown]"
> + try:
> + if self.session:
> + thread_info = self.session.find_thread(sample.sample_tid)
> + if thread_info:
> + comm = thread_info.comm()
> + except (TypeError, AttributeError):
> + pass
> +
> + cpu = sample.sample_cpu
> + addr = sample.sample_addr
> +
> + if CPU_DATA.get(str(cpu) + 'addr') is None:
> + CPU_DATA[str(cpu) + 'addr'] = addr
> + return
> +
> + if dso == '[unknown]':
> + return
> +
> + if dso_start is None or dso_end is None:
> + print(f"Failed to find valid dso map for dso {dso}")
> + return
> +
> + if ev_name.startswith("instructions"):

Could this startswith check unconditionally fail?

The __str__ method for perf.evsel objects returns a formatted string like
"evsel(instructions)", not the raw event name "instructions".

Because of this formatting, the filters ev_name.startswith("instructions")
and ev_name.startswith("branches") will evaluate to false for all events,
causing them to be silently dropped without processing.

> + print_srccode(comm, sample, symbol, dso)
> + return
> +
> + if not ev_name.startswith("branches"):
> + return
> +
> + self._process_branch(sample, comm, symbol, dso, dso_bid, dso_start, dso_end, map_pgoff)

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260425224951.174663-1-irogers@google.com?part=32