Re: [PATCH 01/12] perf jitdump: Fix extended header read that always fails
[email protected] Wed, 05 Aug 2026 13:46:47 +0000
| Newsgroups | org.kernel.vger.linux-perf-users |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 5 potential issue(= s) to consider: Pre-existing issues: - [High] Missing size validation in `jit_get_next_entry` allows out-of-boun= ds heap access and arbitrary memory exfiltration. - [High] Memory leak of the `event` structure in `jit_repipe_code_move`. - [High] Memory leak of `debug_data` and `unwinding_data` buffers. - [Medium] Undefined behavior from calling `funlockfile()` on an unlocked s= tream during early initialization error paths. - [Low] Ineffective use of `flockfile()` for cross-process file synchroniza= tion. -- --- Patch [1]: [PATCH 01/12] perf jitdump: Fix extended header read that al= ways fails --- commit 9c0b715100e3938e32e2120f1ac2090e75d6c0a1 Author: Arnaldo Carvalho de Melo <[email protected]> perf jitdump: Fix extended header read that always fails This commit fixes an issue where jit_open() sets bsz =3D bs before the fread() that uses bs - bsz as the read size, making the read size zero. It separates the buffer growth from the read to ensure extended header bytes are correctly consumed. > diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c > index 83005b30b9bf3..4b7c7ba7cd95d 100644 > --- a/tools/perf/util/jitdump.c > +++ b/tools/perf/util/jitdump.c > @@ -224,10 +224,12 @@ jit_open(struct jit_buf_desc *jd, const char *name) > n =3D realloc(buf, bs); > if (!n) > goto error; > - bsz =3D bs; > buf =3D n; > - /* read extra we do not know about */ > - ret =3D fread(buf, bs - bsz, 1, jd->in); > + bsz =3D bs; > + } > + if (bs > 0) { > + /* consume extended header bytes from the stream */ > + ret =3D fread(buf, bs, 1, jd->in); > if (ret !=3D 1) > goto error; > } [Severity: Medium] This is a pre-existing issue, but I noticed a potential problem in the error handling earlier in jit_open(). When the initial buffer allocation fails: buf =3D malloc(bsz); if (!buf) goto error; /* * protect from writer modifying the file while we are reading it */ flockfile(jd->in); // ... error: free(buf); funlockfile(jd->in); Does this cause undefined behavior by calling funlockfile() on a stream that was never locked by flockfile()? [Severity: Low] This isn't a bug introduced by this patch, but is flockfile() providing the intended synchronization here? /* * protect from writer modifying the file while we are reading it */ flockfile(jd->in); The comment mentions protecting against a writer modifying the file while reading, but flockfile() only provides thread-level synchronization within = the same process. It doesn't lock the file descriptor at the OS level against a separate JIT compiler process. Might a file-level lock be needed instead? [Severity: High] This is a pre-existing issue, but could we have an out-of-bounds heap access when reading the record prefix? In jit_get_next_entry(), the bounds check only verifies the prefix size: bs =3D (size_t)size; if (bs < sizeof(*prefix)) return NULL; If a malformed file provides a prefix->total_size smaller than the specific record struct (e.g., 17 bytes instead of the 56 bytes needed for struct jr_code_load), the fread() will succeed but leave stale data. Later, functions like jit_repipe_code_load() use this stale heap data: csize =3D jr->load.code_size; // ... code =3D (unsigned long)jr + jr->load.p.total_size - csize; Can this result in an out-of-bounds pointer calculation and arbitrary memory being exfiltrated to the output ELF file? [Severity: High] This is a pre-existing issue, but does jit_repipe_code_move() leak the event structure? event =3D calloc(1, sizeof(*event) + 16); if (!event) return -1; // ... out: perf_sample__exit(&sample); return ret; Unlike other repipe functions that free the event, the event pointer here appears to go out of scope without being freed, potentially causing the tool to OOM on large dumps with many JIT_CODE_MOVE records. [Severity: High] This is a pre-existing issue, but is there a memory leak when processing de= bug info records? In jit_repipe_debug_info(), memory is allocated and assigned unconditionall= y: data =3D malloc(sz); if (!data) return -1; memcpy(data, &jr->info.entries, sz); jd->debug_data =3D data; This replaces jd->debug_data without freeing any previously held allocation. Additionally, in jit_process(): nsinfo__put(jd.nsi); free(jd.buf); return ret; It looks like jd.debug_data and jd.unwinding_data are not cleaned up when processing finishes. Should these buffers be freed? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260805133013.2350= [email protected]?part=3D1