[PATCH 03/12] perf jitdump: Prevent integer underflow in debug info size calculation
Arnaldo Carvalho de Melo <[email protected]> Wed, 5 Aug 2026 10:30:02 -0300
| Newsgroups | org.kernel.vger.linux-perf-users,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Arnaldo Carvalho de Melo <[email protected]> jit_repipe_debug_info() and jit_repipe_unwinding_info() compute payload sizes by subtracting the fixed header size from total_size: sz = jr->prefix.total_size - sizeof(jr->info); When total_size is smaller than the header struct (from a truncated or corrupted jitdump record), the subtraction underflows to a massive value, causing an oversized allocation followed by an OOB memcpy. Validate that total_size covers at least the fixed header before the subtraction in both functions. Fixes: 598b7c6919c7 ("perf jit: add source line info support") Fixes: 0284fecd13b6 ("perf jit: Add unwinding support") Reported-by: sashiko-bot <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Stefano Sanfilippo <[email protected]> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> --- tools/perf/util/jitdump.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 3195f94187164066..787f8a03dae87908 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -669,6 +669,10 @@ static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr) if (!(jd && jr)) return -1; + /* total_size must cover at least the fixed header */ + if (jr->prefix.total_size < sizeof(jr->info)) + return -1; + sz = jr->prefix.total_size - sizeof(jr->info); data = malloc(sz); if (!data) @@ -696,6 +700,10 @@ jit_repipe_unwinding_info(struct jit_buf_desc *jd, union jr_entry *jr) if (!(jd && jr)) return -1; + /* total_size must cover at least the fixed header */ + if (jr->prefix.total_size < sizeof(jr->unwinding)) + return -1; + unwinding_data_size = jr->prefix.total_size - sizeof(jr->unwinding); unwinding_data = malloc(unwinding_data_size); if (!unwinding_data) -- 2.55.0