Re: [PATCH v3 1/6] perf mem: Fix size tracking for mem_lvl's in perf_script__meminfo_scnprintf()

[email protected] Mon, 03 Aug 2026 20:54:50 +0000
Newsgroups org.kernel.vger.linux-perf-users
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(=
s) to consider:

Pre-existing issues:
- [Critical] Insufficient stack buffer size and unsafe string operations in=
 memory event formatting lead to severe integer underflows and stack buffer=
 overflows.
--

--- Patch [1]: [PATCH v3 1/6] perf mem: Fix size tracking for mem_lvl's in =
perf_script__meminfo_scnprintf() ---
commit ac4418d3c38063a8fbcd5e19348324171261d3d5
Author: Thomas Falcon <[email protected]>

perf mem: Fix size tracking for mem_lvl's in perf_script__meminfo_scnprintf=
()

When printing memory info in perf script, the entire size of the
buffer is passed to perf_mem__lvl_scnprintf() instead of the remaining
size. Pass the remaining buffer size instead.

> diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
> index 0b49fce251fcc..4e490f9cd3488 100644
> --- a/tools/perf/util/mem-events.c
> +++ b/tools/perf/util/mem-events.c
> @@ -610,7 +610,7 @@ int perf_script__meminfo_scnprintf(char *out, size_t =
sz, const struct mem_info *
>  	i +=3D scnprintf(out, sz, "|OP ");
>  	i +=3D perf_mem__op_scnprintf(out + i, sz - i, mem_info);
>  	i +=3D scnprintf(out + i, sz - i, "|LVL ");
> -	i +=3D perf_mem__lvl_scnprintf(out + i, sz, mem_info);
> +	i +=3D perf_mem__lvl_scnprintf(out + i, sz - i, mem_info);

[Severity: Critical]
This is a pre-existing issue, but by passing sz - i here, does it make it
more likely to hit buffer overflows and integer underflows in the helper
functions?

In tools/perf/builtin-script.c:data_src__fprintf(), a fixed 100-byte stack
buffer is used:

    char decode[100];
    ...
    perf_script__meminfo_scnprintf(decode, 100, mi);

As perf_script__meminfo_scnprintf() accumulates the printed length into i
without bounding it to sz, if the total length exceeds 100 bytes (e.g., with
multiple mem_lvl or snoop flags), i will exceed sz. This causes sz - i to
underflow to a massive size_t value, bypassing bounds checks in subsequent
helper calls.

Additionally, if the remaining size becomes exactly 0 or very small, helpers
like perf_mem__lvl_scnprintf() and perf_mem__snp_scnprintf() do:

    sz -=3D 1; /* -1 for null termination */
    ...
    strcat(out, "Remote ");
    l +=3D 7;

If passed a size of 0, sz -=3D 1 underflows to a massive unsigned value. Un=
checked
strcat() calls will then write out-of-bounds on the stack.

>  	i +=3D scnprintf(out + i, sz - i, "|SNP ");
>  	i +=3D perf_mem__snp_scnprintf(out + i, sz - i, mem_info);
>  	i +=3D scnprintf(out + i, sz - i, "|TLB ");

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260803204540.1003=
[email protected]?part=3D1