diff options
author | Alan Modra <amodra@gmail.com> | 2025-01-01 22:52:59 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-01-01 22:52:59 +1030 |
commit | 94e2b2a770fc49e42c9baec80f4fb88f63391a4e (patch) | |
tree | b6dfb075714ab2e72afd8f18a42e556e2cddab87 | |
parent | 0e4e9aa0a7727819a0b5b240617f8f4243c4c80f (diff) | |
download | binutils-94e2b2a770fc49e42c9baec80f4fb88f63391a4e.zip binutils-94e2b2a770fc49e42c9baec80f4fb88f63391a4e.tar.gz binutils-94e2b2a770fc49e42c9baec80f4fb88f63391a4e.tar.bz2 |
readelf memory leaks
This fixes multiple readelf memory leaks:
- The check functions used to validate separate debug info files
opened and read file data but didn't release the memory nor close
the file.
- A string table was being re-read into a buffer, leaking the old
contents.
- Decompressed section contents leaked.
* dwarf.c (check_gnu_debuglink): Always call close_debug_file.
(check_gnu_debugaltlink): Likewise.
* readelf.c (process_section_headers): Don't read string_table
again if we already have it.
(maybe_expand_or_relocate_section): Add decomp_buf param to
return new uncompressed buffer.
(dump_section_as_strings, filedata->string_table): Free any
uncompressed buffer.
(process_file): Call close_debug_file rather than freeing
various filedata components.
-rw-r--r-- | binutils/dwarf.c | 3 | ||||
-rw-r--r-- | binutils/readelf.c | 32 |
2 files changed, 23 insertions, 12 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 6c8a3c9..626efb2 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -11818,10 +11818,10 @@ check_gnu_debuglink (const char * pathname, void * crc_pointer) crc = calc_gnu_debuglink_crc32 (crc, buffer, count); fclose (f); + close_debug_file (sep_data); if (crc != * (unsigned long *) crc_pointer) { - close_debug_file (sep_data); warn (_("Separate debug info file %s found, but CRC does not match - ignoring\n"), pathname); return false; @@ -11863,6 +11863,7 @@ check_gnu_debugaltlink (const char * filename, void * data ATTRIBUTE_UNUSED) /* FIXME: We should now extract the build-id in the separate file and check it... */ + close_debug_file (sep_data); return true; } diff --git a/binutils/readelf.c b/binutils/readelf.c index f8981f0..4f8f879 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -8171,8 +8171,9 @@ process_section_headers (Filedata * filedata) return false; /* Read in the string table, so that we have names to display. */ - if (filedata->file_header.e_shstrndx != SHN_UNDEF - && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum) + if (filedata->string_table == NULL + && filedata->file_header.e_shstrndx != SHN_UNDEF + && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum) { section = filedata->section_headers + filedata->file_header.e_shstrndx; @@ -16517,6 +16518,7 @@ static uint64_t maybe_expand_or_relocate_section (Elf_Internal_Shdr * section, Filedata * filedata, unsigned char ** start_ptr, + unsigned char ** decomp_buf, bool relocate) { uint64_t section_size = section->sh_size; @@ -16577,7 +16579,10 @@ maybe_expand_or_relocate_section (Elf_Internal_Shdr * section, { if (uncompress_section_contents (is_zstd, &start, uncompressed_size, &new_size, filedata->file_size)) - section_size = new_size; + { + *decomp_buf = start; + section_size = new_size; + } else { error (_("Unable to decompress section %s\n"), @@ -16636,6 +16641,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) unsigned char *end; unsigned char *real_start; unsigned char *start; + unsigned char *decomp_buf; bool some_strings_shown; real_start = start = (unsigned char *) get_section_contents (section, filedata); @@ -16653,7 +16659,9 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section)); - num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false); + decomp_buf = NULL; + num_bytes = maybe_expand_or_relocate_section (section, filedata, &start, + &decomp_buf, false); if (num_bytes == (uint64_t) -1) goto error_out; @@ -16756,12 +16764,14 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) if (! some_strings_shown) printf (_(" No strings found in this section.")); + free (decomp_buf); free (real_start); putchar ('\n'); return true; error_out: + free (decomp_buf); free (real_start); return false; } @@ -16777,6 +16787,7 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, unsigned char *data; unsigned char *real_start; unsigned char *start; + unsigned char *decomp_buf; real_start = start = (unsigned char *) get_section_contents (section, filedata); if (start == NULL) @@ -16793,7 +16804,9 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section)); - section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate); + decomp_buf = NULL; + section_size = maybe_expand_or_relocate_section (section, filedata, &start, + &decomp_buf, relocate); if (section_size == (uint64_t) -1) goto error_out; @@ -16838,12 +16851,14 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, bytes -= lbytes; } + free (decomp_buf); free (real_start); putchar ('\n'); return true; error_out: + free (decomp_buf); free (real_start); return false; } @@ -24193,12 +24208,7 @@ process_file (char * file_name) ret = false; } - fclose (filedata->handle); - free (filedata->section_headers); - free (filedata->program_headers); - free (filedata->string_table); - free (filedata->dump.dump_sects); - free (filedata); + close_debug_file (filedata); free (ba_cache.strtab); ba_cache.strtab = NULL; |