summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2025-06-21 13:43:51 +0200
committerMark Wielaard <[email protected]>2025-06-24 12:26:59 +0200
commit6136fe46258e2292abeab06703610ad58fb91aef (patch)
treed08c7560354e05aebb2cac2827cdce84cf45acf6
parent3cc287a29294bec86380a93020de71d8e8c636ac (diff)
libdwl: Add validate_strdata to limit Elf_Data d_size to valid strings.
dwfl_module_getsym returns the name of a symbol as found in the corresponding (symbol) string section. Make sure all names are correctly zero terminated by making sure the last valid index in a section/segment Elf_Data contains a zero character. * libdwfl/dwfl_module_getdwarf.c (validate_strdata): New function taking Elf_Data and restricting d_size to last zero char. (translate_offs): Call validate_strdata. (find_symtab): Likewise for both symstrdata and aux_symstrdata. https://sourceware.org/bugzilla/show_bug.cgi?id=33099 Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--libdwfl/dwfl_module_getdwarf.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 7fd0d3aa..135132d6 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -1,5 +1,6 @@
/* Find debugging and symbol information for a module in libdwfl.
Copyright (C) 2005-2012, 2014, 2015, 2025 Red Hat, Inc.
+ Copyright (C) 2025 Mark J. Wielaard <[email protected]>
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -692,6 +693,19 @@ find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
}
}
+/* This is a string section/segment, so we want to make sure the last
+ valid index contains a zero character to terminate a string. */
+static void
+validate_strdata (Elf_Data *symstrdata)
+{
+ size_t size = symstrdata->d_size;
+ const char *buf = symstrdata->d_buf;
+ while (size > 0 && *(buf + size - 1) != '\0')
+ --size;
+ symstrdata->d_size = size;
+}
+
+
/* Various addresses we might want to pull from the dynamic segment. */
enum
{
@@ -816,6 +830,8 @@ translate_offs (GElf_Addr adjust,
ELF_T_BYTE);
if (mod->symstrdata == NULL)
mod->symdata = NULL;
+ else
+ validate_strdata (mod->symstrdata);
}
if (mod->symdata == NULL)
mod->symerr = DWFL_E (LIBELF, elf_errno ());
@@ -1181,6 +1197,8 @@ find_symtab (Dwfl_Module *mod)
mod->symstrdata = elf_getdata (symstrscn, NULL);
if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL)
goto elferr;
+ else
+ validate_strdata (mod->symstrdata);
if (xndxscn == NULL)
mod->symxndxdata = NULL;
@@ -1264,6 +1282,8 @@ find_symtab (Dwfl_Module *mod)
mod->aux_symstrdata = elf_getdata (aux_strscn, NULL);
if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL)
goto aux_cleanup;
+ else
+ validate_strdata (mod->aux_symstrdata);
if (aux_xndxscn == NULL)
mod->aux_symxndxdata = NULL;