]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf symbols: Validate p_filesz before use in filename__read_build_id()
authorArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 22:29:34 +0000 (19:29 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 17 Jun 2026 11:25:14 +0000 (08:25 -0300)
filename__read_build_id() stores ELF p_filesz in a ssize_t variable.
A crafted 32-bit ELF with p_filesz = 0xFFFFFFFF produces ssize_t value
-1.  The comparison `p_filesz > buf_size` evaluates false because signed
-1 is less than any non-negative buf_size, so the realloc is skipped and
buf remains NULL.

The subsequent read(fd, NULL, -1) returns -1, which equals p_filesz,
passing the error check.  read_build_id() then dereferences the NULL
buffer.

Add an explicit check for p_filesz <= 0 before using the value,
catching both zero-length and sign-wrapped negative sizes from crafted
ELF files.

Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: ba0b7081f7a521d7 ("perf symbol-minimal: Fix ehdr reading in filename__read_build_id")
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/symbol-minimal.c

index f4b0a711a62cf3def59f2fb9f781edec8dfb4e0d..0a71d146395271a696d697297245279562d2703e 100644 (file)
@@ -186,6 +186,9 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
                        continue;
 
                p_filesz = elf32 ? hdrs.phdr32[i].p_filesz : hdrs.phdr64[i].p_filesz;
+               /* ssize_t can go negative with crafted ELF p_filesz values */
+               if (p_filesz <= 0)
+                       continue;
                if (p_filesz > buf_size) {
                        void *tmp;