[PATCH] segment: Fix dangling pointer
Pointer 'lookup_module' which is a field of the structure 'Dwfl' freed at segment.c:88 is not overwritten, but it is usually overwritten after free. Found by RASU JSC. Signed-off-by: Maks Mishin --- libdwfl/segment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libdwfl/segment.c b/libdwfl/segment.c index f6a3e84e..af76f2f8 100644 --- a/libdwfl/segment.c +++ b/libdwfl/segment.c @@ -86,6 +86,7 @@ insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx) if (unlikely (dwfl->lookup_module == NULL)) { free (old); + old = NULL; return true; } } -- 2.30.2
[PATCH] nm: Fix descriptor leak
The descriptor 'dwfl_fd' is created at nm.c:1278 by calling function 'dup' and lost at nm.c:1593. Found by RASU JSC. Signed-off-by: Maks Mishin --- src/nm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nm.c b/src/nm.c index 3675f59b..fee397dd 100644 --- a/src/nm.c +++ b/src/nm.c @@ -1521,6 +1521,8 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr, } if (dwfl != NULL) dwfl_end (dwfl); + if (dwfl_fd != NULL) +close(dwfl_fd); } -- 2.30.2
[PATCH] readelf: Fix division by zero in handle a relocation sections
Variable 'sh_entsize', whose possible value set allows a zero value by calling function 'gelf_fsize', is used as a denominator in calculation of 'nentries' variable. Found by RASU JSC. Signed-off-by: Maks Mishin --- src/readelf.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/src/readelf.c b/src/readelf.c index 0e931184..6701f5cf 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -2086,6 +2086,12 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) { int class = gelf_getclass (ebl->elf); size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); + + if (sh_entsize == 0) { + printf (_("division by zero in handle_relocs_rel() function")); + return; + } + int nentries = shdr->sh_size / sh_entsize; /* Get the data of the section. */ @@ -2275,6 +2281,12 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) { int class = gelf_getclass (ebl->elf); size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); + + if (sh_entsize == 0) { + printf (_("division by zero in handle_relocs_rela() function")); + return; + } + int nentries = shdr->sh_size / sh_entsize; /* Get the data of the section. */ @@ -2469,6 +2481,12 @@ handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr) { int class = gelf_getclass (ebl->elf); size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT); + + if (sh_entsize == 0) { + printf (_("division by zero in handle_relocs_relr() function")); + return; + } + int nentries = shdr->sh_size / sh_entsize; /* Get the data of the section. */ -- 2.30.2
[PATCH] readelf: Fix deref-of-null in handle_core_item()
Return value of a function 'gelf_getehdr' is dereferenced without checking for NULL, but it is usually checked for this function. Found by RASU JSC. Signed-off-by: Maks Mishin --- src/readelf.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/src/readelf.c b/src/readelf.c index 0e931184..f2ec358f 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -12440,6 +12440,13 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, field went into the high half of USEC. */ GElf_Ehdr ehdr_mem; GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem); + + if (ehdr == NULL) + { + error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1)); + return; + } + if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)) usec >>= 32; else -- 2.30.2
[PATCH] readelf: Fix deref-of-null in handle_core_item()
Signed-off-by: Maks Mishin --- src/readelf.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/src/readelf.c b/src/readelf.c index 0e931184..495db13e 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -12440,6 +12440,13 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, field went into the high half of USEC. */ GElf_Ehdr ehdr_mem; GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem); + if (ehdr == NULL) + { + error (EXIT_FAILURE, 0, +_("cannot read ELF header: %s"), elf_errmsg (-1)); + return; + } + if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)) usec >>= 32; else -- 2.30.2
[PATCH] readelf: Fix deref-of-null in dump_archive_index()
Pointer, returned from function 'elf_getarhdr' ar readelf.c:13551, may be NULL and is dereferenced at readelf.c:13553. Found by RASU JCS. Signed-off-by: Maks Mishin --- src/readelf.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/readelf.c b/src/readelf.c index 0e931184..a650c0b9 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -13549,6 +13549,12 @@ dump_archive_index (Elf *elf, const char *fname) as_off, fname, elf_errmsg (-1)); const Elf_Arhdr *h = elf_getarhdr (subelf); + if (h == NULL) + { + printf ("cannot get archive header in '%s': %s\n", + fname, elf_errmsg (-1)); + return; + } printf (_("Archive member '%s' contains:\n"), h->ar_name); -- 2.30.2
[PATCH] segment: Fix memory leak in insert()
Dynamic memory, referenced by 'naddr', is allocated at segment.c:66 by calling function 'realloc' and lost at segment.c:92. Found by RASU JSC. Signed-off-by: Maks Mishin --- libdwfl/segment.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libdwfl/segment.c b/libdwfl/segment.c index f6a3e84e..5d6053e4 100644 --- a/libdwfl/segment.c +++ b/libdwfl/segment.c @@ -89,6 +89,8 @@ insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx) return true; } } + if (naddr != NULL) + free(naddr); } if (unlikely (i < dwfl->lookup_elts)) -- 2.30.2
[PATCH] segment: Fix memory leak in insert()
Dynamic memory, referenced by 'naddr', is allocated at segment.c:66 by calling function 'realloc' and lost at segment.c:92. Found by RASU JSC. Signed-off-by: Maks Mishin --- libdwfl/segment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libdwfl/segment.c b/libdwfl/segment.c index f6a3e84e..618c14e6 100644 --- a/libdwfl/segment.c +++ b/libdwfl/segment.c @@ -89,6 +89,7 @@ insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx) return true; } } + free (naddr); } if (unlikely (i < dwfl->lookup_elts)) -- 2.30.2
[PATCH] strip: Add check for elf_begin() result
Return value of a function 'elf_begin' is dereferenced at strip.c:1166 without checking for NULL, but it is usually checked for this function. Found by RASU JSC. Signed-off-by: Maks Mishin --- src/strip.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strip.c b/src/strip.c index 6436443d..ebab4866 100644 --- a/src/strip.c +++ b/src/strip.c @@ -1153,7 +1153,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, { /* Also create an ELF descriptor for the debug file */ debugelf = elf_begin (debug_fd, ELF_C_WRITE, NULL); - if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)) + ELF_CHECK (debugelf != NULL, _("cannot create ELF descriptor: %s")); + + if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)) { error (0, 0, _("cannot create new ehdr for file '%s': %s"), debug_fname, elf_errmsg (-1)); -- 2.30.2
[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
[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
[PATCH] Fix some potential deref-of-null error
strip.c: Pointer `arhdr` created at strip.c:2741 and then dereferenced without NULL-check. The same situation for the `arhdr` pointer at the objdump.c:313 and the `h` pointer at the readelf.c:13545. Triggers found by static analyzer Svace. Signed-off-by: Maks Mishin --- src/objdump.c | 5 + src/readelf.c | 5 + src/strip.c | 5 + 3 files changed, 15 insertions(+) diff --git a/src/objdump.c b/src/objdump.c index d43c1dd6..8ad8cdb5 100644 --- a/src/objdump.c +++ b/src/objdump.c @@ -311,6 +311,11 @@ 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 arhdr: %s\n", elf_errmsg (-1)); + exit (1); + } /* Skip over the index entries. */ if (strcmp (arhdr->ar_name, "/") != 0 diff --git a/src/readelf.c b/src/readelf.c index 48035264..96d7877c 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -13543,6 +13543,11 @@ dump_archive_index (Elf *elf, const char *fname) as_off, fname, elf_errmsg (-1)); const Elf_Arhdr *h = elf_getarhdr (subelf); + if (h == NULL) + { + printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); + exit (1); + } printf (_("Archive member '%s' contains:\n"), h->ar_name); diff --git a/src/strip.c b/src/strip.c index 403e0f6f..44389c9b 100644 --- a/src/strip.c +++ b/src/strip.c @@ -2739,6 +2739,11 @@ 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 arhdr: %s\n", elf_errmsg (-1)); + exit (1); + } if (elf_kind (subelf) == ELF_K_ELF) result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); -- 2.30.2
[PATCH] elflint: Fix memory leak in check_gnu_hash function
Dynamic memory, referenced by 'collected', is allocated at elflint.c:2235 and lost at elflint.c:2296. Found by RASU JSC with SVACE. Signed-off-by: Maks Mishin --- src/elflint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/elflint.c b/src/elflint.c index e56e1465..cdc6108d 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -2293,6 +2293,7 @@ section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"), idx, section_name (ebl, idx), symidx, cnt - (4 + bitmask_words)); + free (collected.p32); return; } if (classbits == 32) -- 2.34.1
Re: [PATCH] elflint: Fix memory leak in check_gnu_hash function
Thanks for the feedback! пт, 20 сент. 2024 г. в 19:07, Aaron Merey : > Hi Maks, > > On Wed, Sep 18, 2024 at 4:58 AM Maks Mishin > wrote: > > > > Dynamic memory, referenced by 'collected', is allocated at elflint.c:2235 > > and lost at elflint.c:2296. > > > > Found by RASU JSC with SVACE. > > > > Signed-off-by: Maks Mishin > > --- > > src/elflint.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/src/elflint.c b/src/elflint.c > > index e56e1465..cdc6108d 100644 > > --- a/src/elflint.c > > +++ b/src/elflint.c > > @@ -2293,6 +2293,7 @@ section [%2d] '%s': hash value for symbol %u in > chain for bucket %zu wrong\n"), > > section [%2d] '%s': mask index for symbol %u in chain for bucket %zu > wrong\n"), > > idx, section_name (ebl, idx), symidx, > > cnt - (4 + bitmask_words)); > > + free (collected.p32); > > return; > > } > > if (classbits == 32) > > -- > > 2.34.1 > > > > Thanks, merged as commit b47bdee08a1607 > > Aaron > > -- С уважением, Мишин Максим Александрович +7 (915) 958-41-07 maks.mishi...@gmail.com