[Bug tools/32864] "eu-readelf: bad dynamic symbol" error on ELF without DT_VERSYM
https://sourceware.org/bugzilla/show_bug.cgi?id=32864 Aaron Merey changed: What|Removed |Added CC||amerey at redhat dot com --- Comment #2 from Aaron Merey --- Thanks for the detailed bug report. I've posted a patch to elfutils-devel based on your sample patch. https://sourceware.org/pipermail/elfutils-devel/2025q2/008084.html -- You are receiving this mail because: You are on the CC list for the bug.
[PATCH] src/readelf.c: Access symbol and version data only if available
handle_dynamic_symtab can attempt to read symbol and version data from file offset 0 if the associated DT_ tags aren't found. Fix this by only reading symbol and version data when non-zero file offsets have been found. https://sourceware.org/bugzilla/show_bug.cgi?id=32864 Suggested-by: Constantine Bytensky Signed-off-by: Aaron Merey --- src/readelf.c | 50 +++--- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/readelf.c b/src/readelf.c index 5b0e7b47..0452977f 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3047,18 +3047,25 @@ handle_dynamic_symtab (Ebl *ebl) Elf_Data *verdef_data = NULL; Elf_Data *verneed_data = NULL; - symdata = elf_getdata_rawchunk ( - ebl->elf, offs[i_symtab], - gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM); - symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz], - ELF_T_BYTE); - versym_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF); + if (offs[i_symtab] != 0) +symdata = elf_getdata_rawchunk ( + ebl->elf, offs[i_symtab], + gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM); + + if (offs[i_strtab] != 0) +symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz], + ELF_T_BYTE); + + if (offs[i_versym] != 0) +versym_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF); /* Get the verneed_data without vernaux. */ - verneed_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed), - ELF_T_VNEED); + if (offs[i_verneed] != 0) +verneed_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed), + ELF_T_VNEED); + size_t vernauxnum = 0; size_t vn_next_offset = 0; @@ -3071,14 +3078,18 @@ handle_dynamic_symtab (Ebl *ebl) } /* Update the verneed_data to include the vernaux. */ - verneed_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verneed], - (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), ELF_T_VNEED); + if (offs[i_verneed] != 0) +verneed_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verneed], + (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), + ELF_T_VNEED); /* Get the verdef_data without verdaux. */ - verdef_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef), - ELF_T_VDEF); + if (offs[i_verdef] != 0) +verdef_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef), + ELF_T_VDEF); + size_t verdauxnum = 0; size_t vd_next_offset = 0; @@ -3091,9 +3102,10 @@ handle_dynamic_symtab (Ebl *ebl) } /* Update the verdef_data to include the verdaux. */ - verdef_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verdef], - (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF); + if (offs[i_verdef] != 0) +verdef_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verdef], + (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF); unsigned int nsyms = (unsigned int)syments; process_symtab (ebl, nsyms, 0, 0, 0, symdata, versym_data, symstrdata, -- 2.49.0
Re: [PATCH v2] libdwfl: resolve all paths relative to sysroot
Hi Michal, On Tue, Apr 1, 2025 at 2:56 PM Michal Sekletar wrote: > > Whenever possible, resolve all symlinks as if the sysroot path were a > chroot environment. This prevents potential interactions with files from > the host filesystem. > > Signed-off-by: Michal Sekletar > --- > configure.ac | 26 ++ > libdwfl/dwfl_segment_report_module.c | 39 +-- > libdwfl/link_map.c | 32 +- > tests/run-sysroot.sh | 32 ++ > tests/testfile-sysroot-link.tar.bz2 | Bin 0 -> 2334030 bytes > 5 files changed, 120 insertions(+), 9 deletions(-) > create mode 100644 tests/testfile-sysroot-link.tar.bz2 > > diff --git a/configure.ac b/configure.ac > index 1679a17d..27ea7153 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -283,6 +283,32 @@ case "$CFLAGS" in > ;; > esac > > +AC_CACHE_CHECK( > + [for openat2 with RESOLVE_IN_ROOT support], > + [eu_cv_openat2_RESOLVE_IN_ROOT], > + [AC_LINK_IFELSE( > +[AC_LANG_PROGRAM( > + [[#define _GNU_SOURCE > +#include > +#include > +#include > +#include > +#include > +#include > + ]], [[ > +struct open_how how = { .flags = O_RDONLY|O_DIRECTORY, .resolve = > RESOLVE_IN_ROOT }; > +int dfd = open (".", O_PATH); > +return syscall (SYS_openat2, dfd, ".", &how, sizeof(how)) < 0; > + ]] > +)], > +[eu_cv_openat2_RESOLVE_IN_ROOT=yes], > +[eu_cv_openat2_RESOLVE_IN_ROOT=no] > + )] > +) > +AS_IF([test "x$eu_cv_openat2_RESOLVE_IN_ROOT" = xyes], > + [AC_DEFINE([HAVE_OPENAT2_RESOLVE_IN_ROOT], [1], [Define if openat2 is > available])] > +) > + > dnl enable debugging of branch prediction. > AC_ARG_ENABLE([debugpred], > AS_HELP_STRING([--enable-debugpred],[build binaries with support to debug > branch prediction]), > diff --git a/libdwfl/dwfl_segment_report_module.c > b/libdwfl/dwfl_segment_report_module.c > index 32f44af8..ee723114 100644 > --- a/libdwfl/dwfl_segment_report_module.c > +++ b/libdwfl/dwfl_segment_report_module.c > @@ -37,6 +37,12 @@ > #include > #include > > +#if HAVE_OPENAT2_RESOLVE_IN_ROOT > +#include > +#include > +#include > +#endif > + > #include > > > @@ -784,18 +790,35 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const > char *name, > sysroot if it is set. */ >if (dwfl->sysroot && !executable) > { > - int r; > - char *n; > +#ifdef HAVE_OPENAT2_RESOLVE_IN_ROOT > + int sysrootfd; > + struct open_how how = { > + .flags = O_RDONLY, > + .resolve = RESOLVE_IN_ROOT, > + }; > + > + sysrootfd = open (dwfl->sysroot, O_DIRECTORY|O_PATH); > + if (sysrootfd < 0) > + return -1; > > - r = asprintf (&n, "%s%s", dwfl->sysroot, name); > - if (r > 0) > + fd = syscall (SYS_openat2, sysrootfd, name, &how, sizeof(how)); > + close (sysrootfd); > + > + if (fd < 0 && errno == ENOSYS) > +#endif > { > - fd = open (n, O_RDONLY); > - free (n); > + int r; > + char *n; > + r = asprintf (&n, "%s%s", dwfl->sysroot, name); > + if (r > 0) > + { > + fd = open (n, O_RDONLY); > + free (n); > + } > } > -} > + } >else > - fd = open (name, O_RDONLY); > + fd = open (name, O_RDONLY); > >if (fd >= 0) > { > diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c > index 8ab14862..c52ed041 100644 > --- a/libdwfl/link_map.c > +++ b/libdwfl/link_map.c > @@ -34,6 +34,12 @@ > > #include > > +#if HAVE_OPENAT2_RESOLVE_IN_ROOT > +#include > +#include > +#include > +#endif > + > /* This element is always provided and always has a constant value. > This makes it an easy thing to scan for to discern the format. */ > #define PROBE_TYPE AT_PHENT > @@ -418,7 +424,30 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t > elfdata, > /* This code is mostly inlined dwfl_report_elf. */ > char *sysroot_name = NULL; > const char *sysroot = dwfl->sysroot; > + int fd; > + > +#ifdef HAVE_OPENAT2_RESOLVE_IN_ROOT > + if (sysroot) > + { > + int sysrootfd; > + > + struct open_how how = { > + .flags = O_RDONLY, > + .resolve = RESOLVE_IN_ROOT, > + }; > > + sysrootfd = open (sysroot, O_DIRECTORY|O_PATH); > + if (sysrootfd < 0) > + return -1; > + > + fd = syscall (SYS_openat2, sysrootfd, name, &how, sizeof(how)); > + close (sysrootfd); > + > + /* Fallback to regular open() is openat2 is not available. */ > + if (fd < 0 && errno == ENOSYS) > + fd = open (name, O_RDONLY); > + }
Re: [PATCH] libdw: Add Nim language and dwarf_srclang tests
Hi Mark, On Wed, Apr 2, 2025 at 8:50 AM Mark Wielaard wrote: > > DW_LANG_Nim and DW_LNAME_Nim were added to the DWARF languages. > > While adding them, and the default lower bounds, I noticed DW_LANG_V > and DW_LANG_Algol68 where missing in srclang_to_language an internal > helper function. > > Testing through the public api is not that easy since you need a > Dwarf_Die with the right attributes. So this patch adds a way to > compile an individual source file with an optional main function that > can directly access the internal/static functions. > > Note that it is almost generic. But even though using .SECONDEXPANSION > I couldn't figure out how to create the equivalent of a rule starting > with %_check$(EXEEXT) target. So for now the rule has to repeated for > every new _check TEST. And there needs to be a line to tell make dist > to not expect the fake source: nodist_src_check_SOURCES = src_check.c > > The new test pointed out that there were a few more bugs with > DW_LANG_Dylan and DW_LNAME_Mojo. Also fix those. > > * libdw/dwarf.h: Add DW_LANG_Nim and DW_LNAME_Nim. > * libdw/Makefile.am: Add check_PROGRAMS and TESTS for > dwarf_srclang_check. > * libdw/dwarf_default_lower_bound.c > (dwarf_default_lower_bound): Add DW_LANG_Nim. > (dwarf_language_lower_bound): Add DW_LNAME_Nim. > * libdw/dwarf_srclang.c (srclang_to_language): Handle > DW_LANG_Dylan, DW_LANG_V, DW_LANG_Algol68 and DW_LANG_Nim. > (language_to_srclang): Fix DW_LNAME_Mojo. Add DW_LNAME_Nim. > (test_lang): New function guarded by MAIN_CHECK. > (main): Likewise. > > Signed-off-by: Mark Wielaard LGTM. The optional main function approach opens up a lot of possibilities for testing static functions throughout all elfutils libraries. Aaron