]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf symbols: Bounds-check descsz in sysfs__read_build_id() GNU fallback
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Jun 2026 01:40:20 +0000 (22:40 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 21:56:01 +0000 (18:56 -0300)
When sysfs__read_build_id() matches NT_GNU_BUILD_ID with the right
namesz but the name content is not "GNU", it falls back to reading
descsz bytes into the stack buffer bf[BUFSIZ]:

    } else if (read(fd, bf, descsz) != (ssize_t)descsz)

Unlike the else branch which validates namesz + descsz against
sizeof(bf), this path passes descsz directly to read() without any
bounds check.  A crafted sysfs file with a large n_descsz overflows
the 8192-byte stack buffer.

Add a descsz > sizeof(bf) check before the read, breaking out of
the loop on oversized values.

Fixes: e5a1845fc0aeca85 ("perf symbols: Split out util/symbol-elf.c")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/symbol-elf.c

index 36a0304707e131389035ad06dbfe5f4f985663b4..06cfb84f86eb2f6492ffbae29b4ff9192ff3cd7e 100644 (file)
@@ -961,8 +961,13 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
                                        err = 0;
                                        break;
                                }
-                       } else if (read(fd, bf, descsz) != (ssize_t)descsz)
-                               break;
+                       } else {
+                               /* descsz from untrusted file — clamp to buffer */
+                               if (descsz > sizeof(bf))
+                                       break;
+                               if (read(fd, bf, descsz) != (ssize_t)descsz)
+                                       break;
+                       }
                } else {
                        size_t n;