Re: [PATCH 02/11] perf tools: Use scnprintf() in cpu_map__snprint() to prevent overflow
From: Ian Rogers
Date: Mon Jun 08 2026 - 17:43:14 EST
On Mon, Jun 8, 2026 at 1:18 PM Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> wrote:
>
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> cpu_map__snprint() accumulates snprintf() return values in ret.
> snprintf() returns the number of characters that *would have been
> written* on truncation, not the actual count. When a fragmented CPU
> list exceeds the buffer, ret grows past size, causing `size - ret` to
> underflow (both are size_t), and subsequent snprintf() calls write
> past the end of the caller's stack buffer.
>
> Switch to scnprintf() which returns the actual number of characters
> written, making ret accumulation safe by construction.
>
> Fixes: a24020e6b7cf6eb8 ("perf tools: Change cpu_map__fprintf output")
> Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
> Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
> Cc: Ian Rogers <irogers@xxxxxxxxxx>
> Assisted-by: Claude Opus 4.6 <noreply@xxxxxxxxxxxxx>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>
Thanks,
Ian
> ---
> tools/perf/util/cpumap.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 1fab00ec4a59a0c7..23ebe9b97f8e58af 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -692,21 +692,21 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
> if (start == -1) {
> start = i;
> if (last) {
> - ret += snprintf(buf + ret, size - ret,
> - "%s%d", COMMA,
> - perf_cpu_map__cpu(map, i).cpu);
> + ret += scnprintf(buf + ret, size - ret,
> + "%s%d", COMMA,
> + perf_cpu_map__cpu(map, i).cpu);
> }
> } else if (((i - start) != (cpu.cpu - perf_cpu_map__cpu(map, start).cpu)) || last) {
> int end = i - 1;
>
> if (start == end) {
> - ret += snprintf(buf + ret, size - ret,
> - "%s%d", COMMA,
> - perf_cpu_map__cpu(map, start).cpu);
> + ret += scnprintf(buf + ret, size - ret,
> + "%s%d", COMMA,
> + perf_cpu_map__cpu(map, start).cpu);
> } else {
> - ret += snprintf(buf + ret, size - ret,
> - "%s%d-%d", COMMA,
> - perf_cpu_map__cpu(map, start).cpu, perf_cpu_map__cpu(map, end).cpu);
> + ret += scnprintf(buf + ret, size - ret,
> + "%s%d-%d", COMMA,
> + perf_cpu_map__cpu(map, start).cpu, perf_cpu_map__cpu(map, end).cpu);
> }
> first = false;
> start = i;
> --
> 2.54.0
>