]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf intel-pt: Fix snprintf size tracking bug in insn decoder
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Jun 2026 00:06:54 +0000 (21:06 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 21:56:01 +0000 (18:56 -0300)
dump_insn() tracks remaining buffer space with a 'left' variable,
but the loop subtracts the cumulative offset 'n' each iteration
instead of just the per-iteration delta:

    n += snprintf(x->out + n, left, "%02x ", inbuf[i]);
    left -= n;  /* BUG: n is cumulative, not the delta */

After two iterations left goes massively negative, wrapping to a
huge value when passed as size_t to snprintf(), disabling all bounds
checking for the rest of the loop.

Switch to scnprintf() accumulation using sizeof(x->out) - n as the
remaining space, which is always correct and eliminates the separate
'left' variable entirely.

Fixes: 48d02a1d5c137d36 ("perf script: Add 'brstackinsn' for branch stacks")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c

index 72c7a4e15d617b6021abeea1f1d62987792617e0..f90fcbc4302df58fb45cfa98432998cf0bb76e73 100644 (file)
@@ -220,7 +220,6 @@ const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused,
 {
        struct insn insn;
        int n, i, ret;
-       int left;
 
        ret = insn_decode(&insn, inbuf, inlen,
                          x->is64bit ? INSN_MODE_64 : INSN_MODE_32);
@@ -229,13 +228,9 @@ const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused,
                return "<bad>";
        if (lenp)
                *lenp = insn.length;
-       left = sizeof(x->out);
-       n = snprintf(x->out, left, "insn: ");
-       left -= n;
-       for (i = 0; i < insn.length; i++) {
-               n += snprintf(x->out + n, left, "%02x ", inbuf[i]);
-               left -= n;
-       }
+       n = scnprintf(x->out, sizeof(x->out), "insn: ");
+       for (i = 0; i < insn.length; i++)
+               n += scnprintf(x->out + n, sizeof(x->out) - n, "%02x ", inbuf[i]);
        return x->out;
 }