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 <m...@klomp.org> --- libdwfl/dwfl_module_getdwarf.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index 7fd0d3aa3b17..135132d69178 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 <m...@klomp.org> 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; -- 2.49.0