Re: [PATCH 02/12] perf jitdump: Validate code_size against total_size in code load

Ian Rogers <[email protected]> Wed, 5 Aug 2026 11:58:17 -0700
Newsgroups org.kernel.vger.linux-perf-users,org.kernel.vger.linux-kernel
Message-ID <CAP-5=fVn_FEioEzuf6g3C9pQHLFSTVSXeHa1MUgNJRcHmAg+Rg@mail.gmail.com>
On Wed, Aug 5, 2026 at 6:31 AM Arnaldo Carvalho de Melo <[email protected]> wrote:
>
> From: Arnaldo Carvalho de Melo <[email protected]>
>
> jit_repipe_code_load() reads code_size from the jitdump record and uses
> it to compute a pointer to the code blob:
>
>   code = (unsigned long)jr + jr->load.p.total_size - csize;
>
> An oversized code_size underflows the pointer arithmetic, causing OOB
> reads into earlier heap memory.  Validate that code_size fits within the
> record (total_size - sizeof(jr->load)) before the pointer computation.
>
> code_size is uint64_t but csize is int; values above INT_MAX wrap
> negative when narrowed into csize, which defeats the bounds check and
> sends the code pointer past the end of the record.  Reject those too.
>
> Fixes: 9b07e27f88b9 ("perf inject: Add jitdump mmap injection support")
> Reported-by: sashiko-bot <[email protected]>
> Cc: Stephane Eranian <[email protected]>
> Assisted-by: Claude:claude-opus-4.6
> Assisted-by: Opencode:mimo-v2.5-free
> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
> ---
>  tools/perf/util/jitdump.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
> index 4b7c7ba7cd95ddbb..3195f94187164066 100644
> --- a/tools/perf/util/jitdump.c
> +++ b/tools/perf/util/jitdump.c
> @@ -9,6 +9,7 @@
>  #include <fcntl.h>
>  #include <unistd.h>
>  #include <inttypes.h>
> +#include <limits.h>

very minor nit: The header files are only partially ordered which
means we may accidentally double include header files later, etc. `git
clang-format` should be able to automatically clean this up.

Reviewed-by: Ian Rogers <[email protected]>

Thanks!
Ian

>  #include <byteswap.h>
>  #include <sys/stat.h>
>  #include <sys/mman.h>
> @@ -450,6 +451,16 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
>         csize = jr->load.code_size;
>         usize = jd->unwinding_mapped_size;
>         addr  = jr->load.code_addr;
> +
> +       /* code blob lives at the end of the record, validate it fits */
> +       if (jr->load.p.total_size < sizeof(jr->load) ||
> +           jr->load.code_size > jr->load.p.total_size - sizeof(jr->load) ||
> +           jr->load.code_size > INT_MAX) {
> +               pr_warning("jitdump: invalid code_size %" PRIu64 " (total_size=%u) in code_load record\n",
> +                          (uint64_t)jr->load.code_size, jr->load.p.total_size);
> +               return -1;
> +       }
> +
>         sym   = (void *)((unsigned long)jr + sizeof(jr->load));
>         code  = (unsigned long)jr + jr->load.p.total_size - csize;
>         count = jr->load.code_index;
> --
> 2.55.0
>