diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-15 20:22:12 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-08-31 09:04:46 -0300 |
| commit | 06c7cf7a072fcd52e68471628c56630d2bdcc650 (patch) | |
| tree | 28324bd042e948d39c7fcea1e8e926eb02040141 /tools/perf | |
| parent | 2bd967f3adcba1d3e54f10b0d8b25f950e4f03fd (diff) | |
| download | linux-next-06c7cf7a072fcd52e68471628c56630d2bdcc650.tar.gz linux-next-06c7cf7a072fcd52e68471628c56630d2bdcc650.zip | |
perf jitdump: Validate code_size against total_size in code load
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 <sashiko-bot@kernel.org>
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Stephane Eranian <eranian@google.com>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/jitdump.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index dcb26d9c6c8f..14bd23c8d196 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> #include <byteswap.h> #include <sys/stat.h> #include <sys/mman.h> @@ -452,6 +453,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; |
