Re: [PATCH V5 2/6] tools/perf: Add AUXTRACE recording support for powerpc HTM

Athira Rajeev <[email protected]>
Newsgroups dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-perf-users
Message-ID <[email protected]>

> On 7 Aug 2026, at 8:29 PM, [email protected] wrote:
> 
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Heap buffer overflow in htm_info_fill() due to undersized PERF_RECORD_AUXTRACE_INFO allocation for HTM evsels covering multiple CPUs.
> - [Low] Missing explicit inclusion of `<string.h>` for `strcmp()`, violating musl libc compatibility guidelines.
> --
> 
> --- Patch [2]: [PATCH V5 2/6] tools/perf: Add AUXTRACE recording support for powerpc HTM ---
> commit 36cc90227b9052ae32b72e6b7df67e4e6bc7ac1e
> Author: Athira Rajeev <[email protected]>
> 
> tools/perf: Add AUXTRACE recording support for powerpc HTM
> 
> Add powerpc perf tool support for the HTM PMU AUXTRACE recording path.
> Introduce htm_recording_init() and the associated auxtrace callbacks so
> perf record can create PERF_RECORD_AUXTRACE records for HTM data.
> 
>> diff --git a/tools/perf/arch/powerpc/util/htm.c b/tools/perf/arch/powerpc/util/htm.c
>> new file mode 100644
>> index 0000000000000..d2fdef4880320
>> --- /dev/null
>> +++ b/tools/perf/arch/powerpc/util/htm.c
>> @@ -0,0 +1,185 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * HTM AUX tracing support
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/types.h>
>> +#include <linux/string.h>
>> +#include <linux/zalloc.h>
> 
> [Severity: Low]
> This isn't a bug, but this file uses strcmp() which is declared in <string.h>.
> Does this code need to explicitly include <string.h> to avoid relying on
> implicit inclusion, which might cause build failures in strictly conformant
> musl libc environments?
> 
> [ ... ]
> 
>> +/* Count htm evsels in the evlist */
>> +static int htm_nr_events(struct evlist *evlist)
>> +{
>> + struct evsel *pos;
>> + int n = 0;
>> +
>> + evlist__for_each_entry(evlist, pos) {
>> + if (!strcmp(evsel__pmu_name(pos), "htm"))
>> + n++;
>> + }
>> + return n;
>> +}
>> +
>> +static size_t htm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>> + struct evlist *evlist)
>> +{
>> + return HTM_AUXTRACE_PRIV_SIZE(htm_nr_events(evlist));
>> +}
> 
> [ ... ]
> 
>> +/*
>> + * Fill the PERF_RECORD_AUXTRACE_INFO private data with:
>> + *   priv[POWERPC_HTM_PMU_TYPE]   = pmu->type of the first htm evsel
>> + *   priv[POWERPC_HTM_NUM_EVENTS] = total number of HTM CPU entries
>> + *   priv[POWERPC_HTM_EVENT_DATA + n*2]     = CPU number for nth entry
>> + *   priv[POWERPC_HTM_EVENT_DATA + n*2 + 1] = attr.config for nth entry
>> + *
>> + * One entry is written per CPU in each evsel's cpu map.  An evsel opened
>> + * with -C 0,1,2 contributes three entries (one per CPU), each carrying
>> + * the same attr.config.  The decode side uses event->auxtrace.cpu to look
>> + * up the matching config and derive (node, chip, core) for the output
>> + * file name.
>> + */
>> +static int
>> +htm_info_fill(struct auxtrace_record *itr,
>> +      struct perf_session *session,
>> +      struct perf_record_auxtrace_info *auxtrace_info,
>> +      size_t priv_size)
>> +{
>> + struct htm_recording *htm_r = container_of(itr, struct htm_recording, itr);
>> + struct evlist *evlist = session->evlist;
>> + struct evsel *pos;
>> + int n = 0;
>> + int expected_n = htm_nr_events(evlist);
>> +
>> + if (priv_size != HTM_AUXTRACE_PRIV_SIZE(expected_n))
>> + return -EINVAL;
>> +
>> + auxtrace_info->type = PERF_AUXTRACE_POWERPC_HTM;
>> + auxtrace_info->priv[POWERPC_HTM_PMU_TYPE] = htm_r->evsel->core.attr.type;
>> + auxtrace_info->priv[POWERPC_HTM_NUM_EVENTS] = expected_n;
>> +
>> + evlist__for_each_entry(evlist, pos) {
>> + struct perf_cpu_map *cpus;
>> + int i, nr;
>> +
>> + if (strcmp(evsel__pmu_name(pos), "htm"))
>> + continue;
>> +
>> + /*
>> + * Emit one (cpu, config) entry for every CPU in this evsel's
>> + * map.  perf record -C 0,1,2 creates one evsel with a
>> + * three-entry cpu map; each CPU gets its own AUX buffer and
>> + * must be individually mapped so the decoder can match
>> + * event->auxtrace.cpu to the correct (node, chip, core).
>> + */
>> + cpus = evsel__cpus(pos);
>> + nr = cpus ? perf_cpu_map__nr(cpus) : 0;
>> +
>> + if (nr > 0) {
>> + for (i = 0; i < nr; i++) {
>> + int cpu = perf_cpu_map__cpu(cpus, i).cpu;
>> +
>> + auxtrace_info->priv[POWERPC_HTM_EVENT_DATA + n * 2]     = cpu;
>> + auxtrace_info->priv[POWERPC_HTM_EVENT_DATA + n * 2 + 1] =
>> + pos->core.attr.config;
>> + n++;
> 
> [Severity: High]
> Does this code overflow the auxtrace_info->priv[] array when an HTM evsel
> covers multiple CPUs?
> 
> The auxtrace_info->priv[] buffer size is calculated by htm_nr_events() above,
> which only counts the total number of HTM evsels. If a user runs perf record
> with a CPU list (e.g., -C 0,1,2), there might be only 1 evsel, resulting in
> space allocated for a single (cpu, config) pair.
> 
> However, this loop iterates over the CPU map and writes a pair for every CPU
> in that evsel (e.g., 3 CPUs), incrementing n past the allocated size.
Thanks for the review
Will address this in next version

Thanks
Athira
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.