diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-07 22:40:20 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-10 18:56:01 -0300 |
| commit | 1b4e9fbdeabc549965e70ac0cd8095d57ff6df06 (patch) | |
| tree | 24da0b02848eef2662c56e061f34873af6cdadd5 /tools/perf | |
| parent | e1a2c9d70b312acc262f6be936dd5bbd9bbc6236 (diff) | |
perf symbols: Bounds-check descsz in sysfs__read_build_id() GNU fallback
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>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/symbol-elf.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 36a0304707e1..06cfb84f86eb 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -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; |
