[PATCH 05/23] perf symbols: Bounds-check .gnu_debuglink section data

From: Arnaldo Carvalho de Melo

Date: Wed Jun 10 2026 - 15:52:54 EST


From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

filename__read_debuglink() copies .gnu_debuglink section data into a
caller-provided buffer via:

strncpy(debuglink, data->d_buf, size);

where size is PATH_MAX. If the ELF section is smaller than size and
lacks a null terminator, strncpy reads past data->d_buf into adjacent
memory. A malformed ELF file can trigger this, potentially causing a
segfault or leaking heap data.

Additionally, strncpy does not guarantee null termination when the
source fills the buffer.

Replace with an explicit memcpy bounded by both the output buffer
size and the actual section data size (data->d_size), followed by
explicit null termination.

Fixes: e5a1845fc0aeca85 ("perf symbols: Split out util/symbol-elf.c")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Assisted-by: Claude Opus 4.6 <noreply@xxxxxxxxxxxxx>
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/util/symbol-elf.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 8fb25a5692b56c53..51e7cfe0f5934875 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1027,7 +1027,14 @@ int filename__read_debuglink(const char *filename, char *debuglink,
goto out_elf_end;

/* the start of this section is a zero-terminated string */
- strncpy(debuglink, data->d_buf, size);
+ if (data->d_size > 0) {
+ size_t len = min(size - 1, data->d_size);
+
+ memcpy(debuglink, data->d_buf, len);
+ debuglink[len] = '\0';
+ } else {
+ debuglink[0] = '\0';
+ }

err = 0;

--
2.54.0