[PATCH 1/2] libdwfl: specify optional sysroot to search for shared libraries and binaries
From: Luke Diamand When searching the list of modules in a core file, if the core was generated on a different system to the current one, we need to look in a sysroot for the various shared objects. For example, we might be looking at a core file from an ARM system using elfutils running on an x86 host. This change adds a new function, dwfl_set_sysroot(), which then gets used when searching for libraries and binaries. Signed-off-by: Luke Diamand Signed-off-by: Michal Sekletar --- libdw/libdw.map | 5 +++ libdwfl/Makefile.am | 1 + libdwfl/core-file.c | 2 +- libdwfl/dwfl_end.c | 1 + libdwfl/dwfl_segment_report_module.c | 20 +- libdwfl/dwfl_set_sysroot.c | 57 libdwfl/libdwfl.h| 6 +++ libdwfl/libdwflP.h | 3 +- libdwfl/link_map.c | 19 +- 9 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 libdwfl/dwfl_set_sysroot.c diff --git a/libdw/libdw.map b/libdw/libdw.map index 3c5ce8dc..552588a9 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -378,3 +378,8 @@ ELFUTILS_0.191 { global: dwarf_cu_dwp_section_info; } ELFUTILS_0.188; + +ELFUTILS_0.192 { + global: +dwfl_set_sysroot; +} ELFUTILS_0.191; diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am index 6b26cd51..57c89604 100644 --- a/libdwfl/Makefile.am +++ b/libdwfl/Makefile.am @@ -67,6 +67,7 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \ dwfl_module_return_value_location.c \ dwfl_module_register_names.c \ dwfl_segment_report_module.c \ + dwfl_set_sysroot.c \ link_map.c core-file.c open.c image-header.c \ dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \ linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \ diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c index 89527d23..3135f884 100644 --- a/libdwfl/core-file.c +++ b/libdwfl/core-file.c @@ -559,7 +559,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable) ndx = 0; do { - int seg = dwfl_segment_report_module (dwfl, ndx, NULL, + int seg = dwfl_segment_report_module (dwfl, ndx, NULL, executable, &dwfl_elf_phdr_memory_callback, elf, core_file_read_eagerly, elf, elf->maximum_size, diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c index a1812407..7b5ac8a1 100644 --- a/libdwfl/dwfl_end.c +++ b/libdwfl/dwfl_end.c @@ -48,6 +48,7 @@ dwfl_end (Dwfl *dwfl) free (dwfl->lookup_addr); free (dwfl->lookup_module); free (dwfl->lookup_segndx); + free (dwfl->sysroot); Dwfl_Module *next = dwfl->modulelist; while (next != NULL) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index dc34e0ae..bd360769 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -288,6 +288,7 @@ read_portion (struct read_state *read_state, int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + const char *executable, Dwfl_Memory_Callback *memory_callback, void *memory_callback_arg, Dwfl_Module_Callback *read_eagerly, @@ -778,7 +779,24 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, name = file_note_name; name_is_final = true; bool invalid = false; - fd = open (name, O_RDONLY); + + /* We were not handed specific executable hence try to look for it in sysroot if + it is set. */ + if (dwfl->sysroot && !executable) +{ + 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); + if (fd >= 0) { Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false); diff --git a/libdwfl/dwfl_set_sysroot.c b/libdwfl/dwfl_set_sysroot.c new file mode 100644 index ..309ccd5d --- /dev/null +++ b/libdwfl/dwfl_set_sysroot.c @@ -0,0 +1,57 @@ +/* Return one of the sources lines of a CU. + Copyright (C) 2024 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of
[PATCH 2/2] eu-stack: add support for sysroot option
From: Luke Diamand Use the dwfl_set_sysroot() function to set the sysroot to be used when analysing a core: e.g. $ eu-stack --core core --sysroot /path/to/sysroot -e crashing_prog Signed-off-by: Luke Diamand Signed-off-by: Michal Sekletar --- src/stack.c | 9 + 1 file changed, 9 insertions(+) diff --git a/src/stack.c b/src/stack.c index f4c5ba8c..da2e66a8 100644 --- a/src/stack.c +++ b/src/stack.c @@ -73,6 +73,7 @@ static int core_fd = -1; static Elf *core = NULL; static const char *exec = NULL; static char *debuginfo_path = NULL; +static const char *sysroot = NULL; static const Dwfl_Callbacks proc_callbacks = { @@ -559,6 +560,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_modules = true; break; +case 'S': + sysroot = arg; + break; + case ARGP_KEY_END: if (core == NULL && exec != NULL) argp_error (state, @@ -592,6 +597,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)), dwfl = dwfl_begin (&core_callbacks); if (dwfl == NULL) error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + if (sysroot && dwfl_set_sysroot (dwfl, sysroot) < 0) + error (EXIT_BAD, 0, "dwfl_set_sysroot"); if (dwfl_core_file_report (dwfl, core, exec) < 0) error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1)); } @@ -675,6 +682,8 @@ main (int argc, char **argv) N_("Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"), 0 }, { "list-modules", 'l', NULL, 0, N_("Show module memory map with build-id, elf and debug files detected"), 0 }, + { "sysroot", 'S', "sysroot", 0, + N_("Set the sysroot to search for libraries referenced from the core file"), 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; -- 2.39.3 (Apple Git-146)
Re: [PATCH 1/2] libdwfl: specify optional sysroot to search for shared libraries and binaries
Hi - > [...] For example, we might be looking at a core file from an ARM > system using elfutils running on an x86 host. [...] Makes sense. By the way, to what extent would debuginfod (serving files from that sysroot) work for this same use case? - FChE
[PATCH] Fix deref-of-null in handle_file_note()
After having been assigned to a NULL value at dwfl_segment_report_module.c:200, pointer 'retval' is dereferenced at dwfl_segment_report_module.c:208 by calling function 'strcmp'. Found by RASU JSC. Signed-off-by: Maks Mishin --- libdwfl/dwfl_segment_report_module.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index dc34e0ae..976d7b79 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -205,7 +205,8 @@ handle_file_note (GElf_Addr module_start, GElf_Addr module_end, return NULL; if (mix == firstix) retval = fptr; - if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0) + if (retval != NULL) +if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0) return NULL; fptr = fnext + 1; } -- 2.30.2
[PATCH] size: Fix deref-of-null in handle_ar() function
Pointer, returned from function 'elf_getarhdr' at size.c:362, may be NULL and is dereferenced at size.c:367. Signed-off-by: Maks Mishin --- src/size.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/src/size.c b/src/size.c index ff8ca075..d6bce203 100644 --- a/src/size.c +++ b/src/size.c @@ -361,6 +361,16 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) /* The the header for this element. */ Elf_Arhdr *arhdr = elf_getarhdr (subelf); + if (arhdr == NULL) + { +printf ("cannot get archive header in '%s': %s\n", + fname, elf_errmsg (-1)); +elf_end (subelf); +elf_end (elf); +close (fd); +return 1; + } + if (elf_kind (subelf) == ELF_K_ELF) handle_elf (subelf, new_prefix, arhdr->ar_name); else if (likely (elf_kind (subelf) == ELF_K_AR)) -- 2.30.2
[PATCH] unstrip: Fix deref-of-null in copy_elided_sections()
Pointer `symstrdata` is dereferenced at unstrip.c:1977 without checking for NULL. Signed-off-by: Maks Mishin --- src/unstrip.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unstrip.c b/src/unstrip.c index d70053de..87bd12de 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -1974,8 +1974,11 @@ more sections in stripped file than debug file -- arguments reversed?")); } } +if (symstrdata != NULL) + { if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL) - error_exit (0, "Not enough memory to create symbol table"); + error_exit (0, "Not enough memory to create symbol table"); + } elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY); -- 2.30.2
Re: [PATCH] size: Fix deref-of-null in handle_ar() function
Maks Mishin writes: > Pointer, returned from function 'elf_getarhdr' at size.c:362, > may be NULL and is dereferenced at size.c:367. > Your other patch has "Found by RASU JSC." but the rest don't. Are they all found by it? If so, please say that. (Also, consider sending the fixes as a series if they're related/from the same analyser tool batch.) > Signed-off-by: Maks Mishin > --- > src/size.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/src/size.c b/src/size.c > index ff8ca075..d6bce203 100644 > --- a/src/size.c > +++ b/src/size.c > @@ -361,6 +361,16 @@ handle_ar (int fd, Elf *elf, const char *prefix, const > char *fname) >/* The the header for this element. */ >Elf_Arhdr *arhdr = elf_getarhdr (subelf); > > + if (arhdr == NULL) > + { > +printf ("cannot get archive header in '%s': %s\n", > + fname, elf_errmsg (-1)); > +elf_end (subelf); > +elf_end (elf); > +close (fd); > +return 1; > + } > + >if (elf_kind (subelf) == ELF_K_ELF) > handle_elf (subelf, new_prefix, arhdr->ar_name); >else if (likely (elf_kind (subelf) == ELF_K_AR))
[PATCH] readelf: Fix memory leak in print_hash_info()
Signed-off-by: Maks Mishin --- src/readelf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/readelf.c b/src/readelf.c index c945b371..48035264 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3597,6 +3597,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, { error (0, 0, _("invalid sh_link value in section %zu"), elf_ndxscn (scn)); + free (counts); return; } -- 2.30.2
[PATCH] sparc_attrs: Fix string overflow
A string is copied into the buffer 's' of size 577 without checking its length first at sparc_attrs.c:95. Found by RASU JSC. Signed-off-by: Maks Mishin --- backends/sparc_attrs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/sparc_attrs.c b/backends/sparc_attrs.c index 974e8fb0..104d4ed3 100644 --- a/backends/sparc_attrs.c +++ b/backends/sparc_attrs.c @@ -32,6 +32,7 @@ #include #include +#include #define BACKEND sparc_ #include "libebl_CPU.h" @@ -92,6 +93,7 @@ sparc_check_object_attribute (Ebl *ebl __attribute__ ((unused)), { if (*s != '\0') s = strcat (s, ","); +assert (strlen(s) + strlen(caps[cap]) < 577); s = strcat (s, caps[cap]); } -- 2.30.2