Fix a memory leak in the testcase fuzz_readelf and use-of-uninitialized-value in print_insn_mwtag and use-of-ninitialized-value in _bfd_xcoff_slurp_armap
This commit is contained in:
parent
ca925beec3
commit
e75efd0f4e
34
Re-asan-more-readelf-leaks.patch
Normal file
34
Re-asan-more-readelf-leaks.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 1bd6175ae79099173c1510d209ad9978129e22c0 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Sat, 14 Mar 2020 18:58:11 +1030
|
||||
Subject: [PATCH] Re: asan: more readelf leaks
|
||||
|
||||
In git commit fd486f32d15e I put some static variables used by
|
||||
get_symbol_for_build_attribute in a file scope ba_cache struct. This
|
||||
was to prevent leaks in get_symbol_for_build_attribute, and to tidy up
|
||||
before readelf exited. The patch wasn't quite right though. When
|
||||
readelf processes more than one file it was possible to double free
|
||||
arrays allocated in get_symbol_for_build_attribute.
|
||||
|
||||
* readelf.c (process_file): Clean ba_cache.
|
||||
---
|
||||
binutils/readelf.c | 2 ++
|
||||
1 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
||||
index 0f8a080..49eb20f 100644
|
||||
--- a/binutils/readelf.c
|
||||
+++ b/binutils/readelf.c
|
||||
@@ -20571,7 +20571,9 @@ process_file (char * file_name)
|
||||
free (filedata);
|
||||
|
||||
free (ba_cache.strtab);
|
||||
+ ba_cache.strtab = NULL;
|
||||
free (ba_cache.symtab);
|
||||
+ ba_cache.symtab = NULL;
|
||||
ba_cache.filedata = NULL;
|
||||
|
||||
return ret;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
481
asan-more-readelf-leaks.patch
Normal file
481
asan-more-readelf-leaks.patch
Normal file
@ -0,0 +1,481 @@
|
||||
From fd486f32d15e3299b905084a697fac6349c43f76 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Fri, 13 Mar 2020 13:21:15 +1030
|
||||
Subject: [PATCH] asan: more readelf leaks
|
||||
|
||||
* elfcomm.c (get_archive_member_name): Always return malloc'd
|
||||
string or NULL.
|
||||
* elfedit.c (process_archive): Tidy memory on all return paths.
|
||||
* readelf.c (process_archive): Likewise.
|
||||
(process_symbol_table): Likewise.
|
||||
(ba_cache): New, replacing ..
|
||||
(get_symbol_for_build_attribute): ..static vars here. Free
|
||||
strtab and symtab before loading new ones. Reject symtab without
|
||||
valid strtab in loop, breaking out of loop on valid symtab.
|
||||
(process_file): Free ba_cache symtab and strtab here, resetting
|
||||
ba_cache.
|
||||
---
|
||||
binutils/elfcomm.c | 8 +--
|
||||
binutils/elfedit.c | 9 ++++
|
||||
binutils/readelf.c | 152 +++++++++++++++++++++++++++++++++--------------------
|
||||
3 files changed, 107 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
|
||||
index 87a544b..3060ff1 100644
|
||||
--- a/binutils/elfcomm.c
|
||||
+++ b/binutils/elfcomm.c
|
||||
@@ -797,7 +797,7 @@ get_archive_member_name (struct archive_info *arch,
|
||||
arch->longnames[j] = '\0';
|
||||
|
||||
if (!arch->is_thin_archive || arch->nested_member_origin == 0)
|
||||
- return arch->longnames + k;
|
||||
+ return xstrdup (arch->longnames + k);
|
||||
|
||||
/* PR 17531: file: 2896dc8b. */
|
||||
if (k >= j)
|
||||
@@ -813,7 +813,7 @@ get_archive_member_name (struct archive_info *arch,
|
||||
if (member_file_name != NULL
|
||||
&& setup_nested_archive (nested_arch, member_file_name) == 0)
|
||||
{
|
||||
- member_name = get_archive_member_name_at (nested_arch,
|
||||
+ member_name = get_archive_member_name_at (nested_arch,
|
||||
arch->nested_member_origin,
|
||||
NULL);
|
||||
if (member_name != NULL)
|
||||
@@ -825,7 +825,7 @@ get_archive_member_name (struct archive_info *arch,
|
||||
free (member_file_name);
|
||||
|
||||
/* Last resort: just return the name of the nested archive. */
|
||||
- return arch->longnames + k;
|
||||
+ return xstrdup (arch->longnames + k);
|
||||
}
|
||||
|
||||
/* We have a normal (short) name. */
|
||||
@@ -833,7 +833,7 @@ get_archive_member_name (struct archive_info *arch,
|
||||
if (arch->arhdr.ar_name[j] == '/')
|
||||
{
|
||||
arch->arhdr.ar_name[j] = '\0';
|
||||
- return arch->arhdr.ar_name;
|
||||
+ return xstrdup (arch->arhdr.ar_name);
|
||||
}
|
||||
|
||||
/* The full ar_name field is used. Don't rely on ar_date starting
|
||||
diff --git a/binutils/elfedit.c b/binutils/elfedit.c
|
||||
index e94b677..3a14c60 100644
|
||||
--- a/binutils/elfedit.c
|
||||
+++ b/binutils/elfedit.c
|
||||
@@ -616,6 +616,7 @@ process_archive (const char * file_name, FILE * file,
|
||||
if (qualified_name == NULL)
|
||||
{
|
||||
error (_("%s: bad archive file name\n"), file_name);
|
||||
+ free (name);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@@ -626,8 +627,10 @@ process_archive (const char * file_name, FILE * file,
|
||||
FILE *member_file;
|
||||
char *member_file_name = adjust_relative_path (file_name,
|
||||
name, namelen);
|
||||
+ free (name);
|
||||
if (member_file_name == NULL)
|
||||
{
|
||||
+ free (qualified_name);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@@ -638,6 +641,7 @@ process_archive (const char * file_name, FILE * file,
|
||||
error (_("Input file '%s' is not readable\n"),
|
||||
member_file_name);
|
||||
free (member_file_name);
|
||||
+ free (qualified_name);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@@ -648,9 +652,12 @@ process_archive (const char * file_name, FILE * file,
|
||||
|
||||
fclose (member_file);
|
||||
free (member_file_name);
|
||||
+ free (qualified_name);
|
||||
}
|
||||
else if (is_thin_archive)
|
||||
{
|
||||
+ free (name);
|
||||
+
|
||||
/* This is a proxy for a member of a nested archive. */
|
||||
archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
|
||||
|
||||
@@ -661,6 +668,7 @@ process_archive (const char * file_name, FILE * file,
|
||||
{
|
||||
error (_("%s: failed to seek to archive member\n"),
|
||||
nested_arch.file_name);
|
||||
+ free (qualified_name);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@@ -669,6 +677,7 @@ process_archive (const char * file_name, FILE * file,
|
||||
}
|
||||
else
|
||||
{
|
||||
+ free (name);
|
||||
archive_file_offset = arch.next_arhdr_offset;
|
||||
arch.next_arhdr_offset += archive_file_size;
|
||||
|
||||
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
||||
index d009b91..4e21bdb 100644
|
||||
--- a/binutils/readelf.c
|
||||
+++ b/binutils/readelf.c
|
||||
@@ -11766,17 +11766,17 @@ process_symbol_table (Filedata * filedata)
|
||||
buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
|
||||
chains = get_dynamic_data (filedata, nchains, hash_ent_size);
|
||||
|
||||
- no_hash:
|
||||
if (buckets == NULL || chains == NULL)
|
||||
{
|
||||
- if (do_using_dynamic)
|
||||
- return FALSE;
|
||||
+ no_hash:
|
||||
free (buckets);
|
||||
free (chains);
|
||||
buckets = NULL;
|
||||
chains = NULL;
|
||||
nbuckets = 0;
|
||||
nchains = 0;
|
||||
+ if (do_using_dynamic)
|
||||
+ goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11833,7 +11833,7 @@ process_symbol_table (Filedata * filedata)
|
||||
if (gnubuckets[i] != 0)
|
||||
{
|
||||
if (gnubuckets[i] < gnusymidx)
|
||||
- return FALSE;
|
||||
+ goto err_out;
|
||||
|
||||
if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
|
||||
maxchain = gnubuckets[i];
|
||||
@@ -11898,21 +11898,17 @@ process_symbol_table (Filedata * filedata)
|
||||
}
|
||||
|
||||
mipsxlat = get_dynamic_data (filedata, maxchain, 4);
|
||||
- }
|
||||
-
|
||||
- no_gnu_hash:
|
||||
- if (dynamic_info_DT_MIPS_XHASH && mipsxlat == NULL)
|
||||
- {
|
||||
- free (gnuchains);
|
||||
- gnuchains = NULL;
|
||||
- }
|
||||
- if (gnuchains == NULL)
|
||||
- {
|
||||
- free (gnubuckets);
|
||||
- gnubuckets = NULL;
|
||||
- ngnubuckets = 0;
|
||||
- if (do_using_dynamic)
|
||||
- return FALSE;
|
||||
+ if (mipsxlat == NULL)
|
||||
+ {
|
||||
+ no_gnu_hash:
|
||||
+ free (gnuchains);
|
||||
+ gnuchains = NULL;
|
||||
+ free (gnubuckets);
|
||||
+ gnubuckets = NULL;
|
||||
+ ngnubuckets = 0;
|
||||
+ if (do_using_dynamic)
|
||||
+ goto err_out;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12129,7 +12125,7 @@ process_symbol_table (Filedata * filedata)
|
||||
if (lengths == NULL)
|
||||
{
|
||||
error (_("Out of memory allocating space for histogram buckets\n"));
|
||||
- return FALSE;
|
||||
+ goto err_out;
|
||||
}
|
||||
visited = xcmalloc (nchains, 1);
|
||||
memset (visited, 0, nchains);
|
||||
@@ -12157,7 +12153,7 @@ process_symbol_table (Filedata * filedata)
|
||||
{
|
||||
free (lengths);
|
||||
error (_("Out of memory allocating space for histogram counts\n"));
|
||||
- return FALSE;
|
||||
+ goto err_out;
|
||||
}
|
||||
|
||||
for (hn = 0; hn < nbuckets; ++hn)
|
||||
@@ -12181,11 +12177,10 @@ process_symbol_table (Filedata * filedata)
|
||||
free (lengths);
|
||||
}
|
||||
|
||||
- if (buckets != NULL)
|
||||
- {
|
||||
- free (buckets);
|
||||
- free (chains);
|
||||
- }
|
||||
+ free (buckets);
|
||||
+ buckets = NULL;
|
||||
+ free (chains);
|
||||
+ chains = NULL;
|
||||
|
||||
if (do_histogram && gnubuckets != NULL)
|
||||
{
|
||||
@@ -12208,7 +12203,7 @@ process_symbol_table (Filedata * filedata)
|
||||
if (lengths == NULL)
|
||||
{
|
||||
error (_("Out of memory allocating space for gnu histogram buckets\n"));
|
||||
- return FALSE;
|
||||
+ goto err_out;
|
||||
}
|
||||
|
||||
printf (_(" Length Number %% of total Coverage\n"));
|
||||
@@ -12234,7 +12229,7 @@ process_symbol_table (Filedata * filedata)
|
||||
{
|
||||
free (lengths);
|
||||
error (_("Out of memory allocating space for gnu histogram counts\n"));
|
||||
- return FALSE;
|
||||
+ goto err_out;
|
||||
}
|
||||
|
||||
for (hn = 0; hn < ngnubuckets; ++hn)
|
||||
@@ -12256,12 +12251,19 @@ process_symbol_table (Filedata * filedata)
|
||||
|
||||
free (counts);
|
||||
free (lengths);
|
||||
- free (gnubuckets);
|
||||
- free (gnuchains);
|
||||
- free (mipsxlat);
|
||||
}
|
||||
-
|
||||
+ free (gnubuckets);
|
||||
+ free (gnuchains);
|
||||
+ free (mipsxlat);
|
||||
return TRUE;
|
||||
+
|
||||
+ err_out:
|
||||
+ free (gnubuckets);
|
||||
+ free (gnuchains);
|
||||
+ free (mipsxlat);
|
||||
+ free (buckets);
|
||||
+ free (chains);
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
@@ -18773,6 +18775,14 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+struct build_attr_cache {
|
||||
+ Filedata *filedata;
|
||||
+ char *strtab;
|
||||
+ unsigned long strtablen;
|
||||
+ Elf_Internal_Sym *symtab;
|
||||
+ unsigned long nsyms;
|
||||
+} ba_cache;
|
||||
+
|
||||
/* Find the symbol associated with a build attribute that is attached
|
||||
to address OFFSET. If PNAME is non-NULL then store the name of
|
||||
the symbol (if found) in the provided pointer, Returns NULL if a
|
||||
@@ -18784,19 +18794,19 @@ get_symbol_for_build_attribute (Filedata * filedata,
|
||||
bfd_boolean is_open_attr,
|
||||
const char ** pname)
|
||||
{
|
||||
- static Filedata * saved_filedata = NULL;
|
||||
- static char * strtab;
|
||||
- static unsigned long strtablen;
|
||||
- static Elf_Internal_Sym * symtab;
|
||||
- static unsigned long nsyms;
|
||||
- Elf_Internal_Sym * saved_sym = NULL;
|
||||
- Elf_Internal_Sym * sym;
|
||||
+ Elf_Internal_Sym *saved_sym = NULL;
|
||||
+ Elf_Internal_Sym *sym;
|
||||
|
||||
if (filedata->section_headers != NULL
|
||||
- && (saved_filedata == NULL || filedata != saved_filedata))
|
||||
+ && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
|
||||
{
|
||||
Elf_Internal_Shdr * symsec;
|
||||
|
||||
+ free (ba_cache.strtab);
|
||||
+ ba_cache.strtab = NULL;
|
||||
+ free (ba_cache.symtab);
|
||||
+ ba_cache.symtab = NULL;
|
||||
+
|
||||
/* Load the symbol and string sections. */
|
||||
for (symsec = filedata->section_headers;
|
||||
symsec < filedata->section_headers + filedata->file_header.e_shnum;
|
||||
@@ -18804,41 +18814,52 @@ get_symbol_for_build_attribute (Filedata * filedata,
|
||||
{
|
||||
if (symsec->sh_type == SHT_SYMTAB)
|
||||
{
|
||||
- symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
|
||||
+ ba_cache.symtab = GET_ELF_SYMBOLS (filedata, symsec,
|
||||
+ &ba_cache.nsyms);
|
||||
|
||||
- if (symsec->sh_link < filedata->file_header.e_shnum)
|
||||
+ if (ba_cache.symtab != NULL
|
||||
+ && symsec->sh_link < filedata->file_header.e_shnum)
|
||||
{
|
||||
- Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
|
||||
-
|
||||
- strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
|
||||
- 1, strtab_sec->sh_size,
|
||||
- _("string table"));
|
||||
- strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
|
||||
+ Elf_Internal_Shdr *strtab_sec
|
||||
+ = filedata->section_headers + symsec->sh_link;
|
||||
+
|
||||
+ ba_cache.strtab
|
||||
+ = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
|
||||
+ 1, strtab_sec->sh_size,
|
||||
+ _("string table"));
|
||||
+ ba_cache.strtablen = strtab_sec->sh_size;
|
||||
}
|
||||
+ if (ba_cache.strtab == NULL)
|
||||
+ {
|
||||
+ free (ba_cache.symtab);
|
||||
+ ba_cache.symtab = NULL;
|
||||
+ }
|
||||
+ if (ba_cache.symtab != NULL)
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
- saved_filedata = filedata;
|
||||
+ ba_cache.filedata = filedata;
|
||||
}
|
||||
|
||||
- if (symtab == NULL || strtab == NULL)
|
||||
+ if (ba_cache.symtab == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Find a symbol whose value matches offset. */
|
||||
- for (sym = symtab; sym < symtab + nsyms; sym ++)
|
||||
+ for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
|
||||
if (sym->st_value == offset)
|
||||
{
|
||||
- if (sym->st_name >= strtablen)
|
||||
+ if (sym->st_name >= ba_cache.strtablen)
|
||||
/* Huh ? This should not happen. */
|
||||
continue;
|
||||
|
||||
- if (strtab[sym->st_name] == 0)
|
||||
+ if (ba_cache.strtab[sym->st_name] == 0)
|
||||
continue;
|
||||
|
||||
/* The AArch64 and ARM architectures define mapping symbols
|
||||
(eg $d, $x, $t) which we want to ignore. */
|
||||
- if (strtab[sym->st_name] == '$'
|
||||
- && strtab[sym->st_name + 1] != 0
|
||||
- && strtab[sym->st_name + 2] == 0)
|
||||
+ if (ba_cache.strtab[sym->st_name] == '$'
|
||||
+ && ba_cache.strtab[sym->st_name + 1] != 0
|
||||
+ && ba_cache.strtab[sym->st_name + 2] == 0)
|
||||
continue;
|
||||
|
||||
if (is_open_attr)
|
||||
@@ -18855,7 +18876,7 @@ get_symbol_for_build_attribute (Filedata * filedata,
|
||||
{
|
||||
/* If the symbol has a size associated
|
||||
with it then we can stop searching. */
|
||||
- sym = symtab + nsyms;
|
||||
+ sym = ba_cache.symtab + ba_cache.nsyms;
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -18895,7 +18916,7 @@ get_symbol_for_build_attribute (Filedata * filedata,
|
||||
}
|
||||
|
||||
if (saved_sym && pname)
|
||||
- * pname = strtab + saved_sym->st_name;
|
||||
+ * pname = ba_cache.strtab + saved_sym->st_name;
|
||||
|
||||
return saved_sym;
|
||||
}
|
||||
@@ -20238,6 +20259,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
putchar ('\n');
|
||||
free (qualified_name);
|
||||
}
|
||||
+ free (member_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20340,6 +20362,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
if (qualified_name == NULL)
|
||||
{
|
||||
error (_("%s: bad archive file name\n"), arch.file_name);
|
||||
+ free (name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -20351,8 +20374,10 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
char * member_file_name = adjust_relative_path
|
||||
(filedata->file_name, name, namelen);
|
||||
|
||||
+ free (name);
|
||||
if (member_file_name == NULL)
|
||||
{
|
||||
+ free (qualified_name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -20362,6 +20387,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
{
|
||||
error (_("Input file '%s' is not readable.\n"), member_file_name);
|
||||
free (member_file_name);
|
||||
+ free (qualified_name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -20374,6 +20400,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
|
||||
close_file (member_filedata);
|
||||
free (member_file_name);
|
||||
+ free (qualified_name);
|
||||
}
|
||||
else if (is_thin_archive)
|
||||
{
|
||||
@@ -20386,9 +20413,12 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
{
|
||||
error (_("%s: contains corrupt thin archive: %s\n"),
|
||||
qualified_name, name);
|
||||
+ free (qualified_name);
|
||||
+ free (name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
+ free (name);
|
||||
|
||||
/* This is a proxy for a member of a nested archive. */
|
||||
archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
|
||||
@@ -20398,6 +20428,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
|
||||
{
|
||||
error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
|
||||
+ free (qualified_name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -20410,6 +20441,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
}
|
||||
else
|
||||
{
|
||||
+ free (name);
|
||||
archive_file_offset = arch.next_arhdr_offset;
|
||||
arch.next_arhdr_offset += archive_file_size;
|
||||
|
||||
@@ -20510,6 +20542,10 @@ process_file (char * file_name)
|
||||
free (filedata->dump_sects);
|
||||
free (filedata);
|
||||
|
||||
+ free (ba_cache.strtab);
|
||||
+ free (ba_cache.symtab);
|
||||
+ ba_cache.filedata = NULL;
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
77
asan-readelf-leaks.patch
Normal file
77
asan-readelf-leaks.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 8fb879cd16a3e3d1fe93e333c4c720fd33bcc416 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Thu, 12 Mar 2020 16:48:07 +1030
|
||||
Subject: [PATCH] asan: readelf leaks
|
||||
|
||||
* readelf.c (process_section_headers): Don't just set
|
||||
filedata->section_headers NULL, free it first. Similarly for
|
||||
dynamic_symbols, dynamic_strings, dynamic_syminfo and
|
||||
symtab_shndx_list. Zero associated counts too.
|
||||
(process_object): Free symtab_shndx_list.
|
||||
(process_file): Free various allocated filedata tables.
|
||||
---
|
||||
binutils/readelf.c | 24 +++++++++++++++++++++++-
|
||||
1 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
||||
index 260ea33..d009b91 100644
|
||||
--- a/binutils/readelf.c
|
||||
+++ b/binutils/readelf.c
|
||||
@@ -6117,6 +6117,7 @@ process_section_headers (Filedata * filedata)
|
||||
Elf_Internal_Shdr * section;
|
||||
unsigned int i;
|
||||
|
||||
+ free (filedata->section_headers);
|
||||
filedata->section_headers = NULL;
|
||||
|
||||
if (filedata->file_header.e_shnum == 0)
|
||||
@@ -6172,10 +6173,20 @@ process_section_headers (Filedata * filedata)
|
||||
|
||||
/* Scan the sections for the dynamic symbol table
|
||||
and dynamic string table and debug sections. */
|
||||
+ free (dynamic_symbols);
|
||||
dynamic_symbols = NULL;
|
||||
+ num_dynamic_syms = 0;
|
||||
+ free (dynamic_strings);
|
||||
dynamic_strings = NULL;
|
||||
+ dynamic_strings_length = 0;
|
||||
+ free (dynamic_syminfo);
|
||||
dynamic_syminfo = NULL;
|
||||
- symtab_shndx_list = NULL;
|
||||
+ while (symtab_shndx_list != NULL)
|
||||
+ {
|
||||
+ elf_section_list *next = symtab_shndx_list->next;
|
||||
+ free (symtab_shndx_list);
|
||||
+ symtab_shndx_list = next;
|
||||
+ }
|
||||
|
||||
eh_addr_size = is_32bit_elf ? 4 : 8;
|
||||
switch (filedata->file_header.e_machine)
|
||||
@@ -20121,6 +20132,13 @@ process_object (Filedata * filedata)
|
||||
dynamic_section = NULL;
|
||||
}
|
||||
|
||||
+ while (symtab_shndx_list != NULL)
|
||||
+ {
|
||||
+ elf_section_list *next = symtab_shndx_list->next;
|
||||
+ free (symtab_shndx_list);
|
||||
+ symtab_shndx_list = next;
|
||||
+ }
|
||||
+
|
||||
if (section_headers_groups)
|
||||
{
|
||||
free (section_headers_groups);
|
||||
@@ -20486,6 +20504,10 @@ process_file (char * file_name)
|
||||
}
|
||||
|
||||
fclose (filedata->handle);
|
||||
+ free (filedata->section_headers);
|
||||
+ free (filedata->program_headers);
|
||||
+ free (filedata->string_table);
|
||||
+ free (filedata->dump_sects);
|
||||
free (filedata);
|
||||
|
||||
return ret;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Summary: Binary utilities
|
||||
Name: binutils
|
||||
Version: 2.34
|
||||
Release: 2
|
||||
Release: 3
|
||||
License: GPLv3+
|
||||
URL: https://sourceware.org/binutils
|
||||
|
||||
@ -28,6 +28,12 @@ Patch12: BFD-Exclude-sections-with-no-content-from-compress-c.patch
|
||||
Patch13: gas-PR-25863-Fix-scalar-vmul-inside-it-block-when-as.patch
|
||||
Patch14: NDS32-disassembly-of-odd-sized-sections.patch
|
||||
|
||||
Patch15: asan-readelf-leaks.patch
|
||||
Patch16: asan-more-readelf-leaks.patch
|
||||
Patch17: Re-asan-more-readelf-leaks.patch
|
||||
Patch18: readelf-leak-in-process_archive.patch
|
||||
Patch19: metag-uninitialized-memory-read.patch
|
||||
|
||||
Provides: bundled(libiberty)
|
||||
|
||||
Buildroot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
@ -314,6 +320,13 @@ fi
|
||||
%{_infodir}/bfd*info*
|
||||
|
||||
%changelog
|
||||
* Fri Sep 11 2020 zoulin <zoulin13@huawei.com> - 2.34-3
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:Fix a memory leak in the testcase fuzz_readelf
|
||||
Fix use-of-uninitialized-value in print_insn_mwtag
|
||||
Fix use-of-ninitialized-value in _bfd_xcoff_slurp_armap
|
||||
|
||||
* Wed Aug 5 2020 zhangxingliang <zhangxingliang3@huawei.com> - 2.34-2
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
36
metag-uninitialized-memory-read.patch
Normal file
36
metag-uninitialized-memory-read.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 340f3ac8082771ecc473ab938fc3d7cbf607ddaa Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Fri, 20 Mar 2020 10:55:58 +1030
|
||||
Subject: [PATCH] metag uninitialized memory read
|
||||
|
||||
* metag-dis.c (print_insn_metag): Don't ignore status from
|
||||
read_memory_func.
|
||||
---
|
||||
opcodes/metag-dis.c | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/opcodes/metag-dis.c b/opcodes/metag-dis.c
|
||||
index f01dcba..b1cf633 100644
|
||||
--- a/opcodes/metag-dis.c
|
||||
+++ b/opcodes/metag-dis.c
|
||||
@@ -3364,9 +3364,15 @@ print_insn_metag (bfd_vma pc, disassemble_info *outf)
|
||||
bfd_byte buf[4];
|
||||
unsigned int insn_word;
|
||||
size_t i;
|
||||
- outf->bytes_per_chunk = 4;
|
||||
+ int status;
|
||||
|
||||
- (*outf->read_memory_func) (pc & ~0x03, buf, 4, outf);
|
||||
+ outf->bytes_per_chunk = 4;
|
||||
+ status = (*outf->read_memory_func) (pc & ~0x03, buf, 4, outf);
|
||||
+ if (status)
|
||||
+ {
|
||||
+ (*outf->memory_error_func) (status, pc, outf);
|
||||
+ return -1;
|
||||
+ }
|
||||
insn_word = bfd_getl32 (buf);
|
||||
|
||||
for (i = 0; i < sizeof(metag_optab)/sizeof(metag_optab[0]); i++)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
283
readelf-leak-in-process_archive.patch
Normal file
283
readelf-leak-in-process_archive.patch
Normal file
@ -0,0 +1,283 @@
|
||||
From 1cb7d8b1afc7c71cfacfe017e0692c9064bf9818 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Thu, 19 Mar 2020 10:10:32 +1030
|
||||
Subject: [PATCH] readelf leak in process_archive
|
||||
|
||||
* readelf.c (process_archive): Always return via path freeing
|
||||
memory. Formatting.
|
||||
---
|
||||
binutils/readelf.c | 166 +++++++++++++++++++++++++++++------------------------
|
||||
1 files changed, 90 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
||||
index c8ca66e..f76b9f6 100644
|
||||
--- a/binutils/readelf.c
|
||||
+++ b/binutils/readelf.c
|
||||
@@ -20256,49 +20256,58 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
if (do_archive_index)
|
||||
{
|
||||
if (arch.sym_table == NULL)
|
||||
- error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
|
||||
+ error (_("%s: unable to dump the index as none was found\n"),
|
||||
+ filedata->file_name);
|
||||
else
|
||||
{
|
||||
unsigned long i, l;
|
||||
unsigned long current_pos;
|
||||
|
||||
- printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
|
||||
- filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
|
||||
+ printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
|
||||
+ "in the symbol table)\n"),
|
||||
+ filedata->file_name, (unsigned long) arch.index_num,
|
||||
+ arch.sym_size);
|
||||
|
||||
current_pos = ftell (filedata->handle);
|
||||
|
||||
for (i = l = 0; i < arch.index_num; i++)
|
||||
{
|
||||
- if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
|
||||
- {
|
||||
- char * member_name;
|
||||
-
|
||||
- member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
|
||||
+ if (i == 0
|
||||
+ || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
|
||||
+ {
|
||||
+ char * member_name
|
||||
+ = get_archive_member_name_at (&arch, arch.index_array[i],
|
||||
+ &nested_arch);
|
||||
|
||||
- if (member_name != NULL)
|
||||
- {
|
||||
- char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
|
||||
+ if (member_name != NULL)
|
||||
+ {
|
||||
+ char * qualified_name
|
||||
+ = make_qualified_name (&arch, &nested_arch,
|
||||
+ member_name);
|
||||
|
||||
- if (qualified_name != NULL)
|
||||
- {
|
||||
- printf (_("Contents of binary %s at offset "), qualified_name);
|
||||
+ if (qualified_name != NULL)
|
||||
+ {
|
||||
+ printf (_("Contents of binary %s at offset "),
|
||||
+ qualified_name);
|
||||
(void) print_vma (arch.index_array[i], PREFIX_HEX);
|
||||
putchar ('\n');
|
||||
- free (qualified_name);
|
||||
- }
|
||||
+ free (qualified_name);
|
||||
+ }
|
||||
free (member_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (l >= arch.sym_size)
|
||||
{
|
||||
- error (_("%s: end of the symbol table reached before the end of the index\n"),
|
||||
+ error (_("%s: end of the symbol table reached "
|
||||
+ "before the end of the index\n"),
|
||||
filedata->file_name);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
/* PR 17531: file: 0b6630b2. */
|
||||
- printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
|
||||
+ printf ("\t%.*s\n",
|
||||
+ (int) (arch.sym_size - l), arch.sym_table + l);
|
||||
l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
|
||||
}
|
||||
|
||||
@@ -20322,7 +20331,8 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
|
||||
if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
|
||||
{
|
||||
- error (_("%s: failed to seek back to start of object files in the archive\n"),
|
||||
+ error (_("%s: failed to seek back to start of object files "
|
||||
+ "in the archive\n"),
|
||||
filedata->file_name);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
@@ -20347,34 +20357,37 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
|
||||
/* Read the next archive header. */
|
||||
if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
|
||||
- {
|
||||
- error (_("%s: failed to seek to next archive header\n"), arch.file_name);
|
||||
- return FALSE;
|
||||
- }
|
||||
+ {
|
||||
+ error (_("%s: failed to seek to next archive header\n"),
|
||||
+ arch.file_name);
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
|
||||
if (got != sizeof arch.arhdr)
|
||||
- {
|
||||
- if (got == 0)
|
||||
+ {
|
||||
+ if (got == 0)
|
||||
break;
|
||||
/* PR 24049 - we cannot use filedata->file_name as this will
|
||||
have already been freed. */
|
||||
error (_("%s: failed to read archive header\n"), arch.file_name);
|
||||
|
||||
- ret = FALSE;
|
||||
- break;
|
||||
- }
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
|
||||
- {
|
||||
- error (_("%s: did not find a valid archive header\n"), arch.file_name);
|
||||
- ret = FALSE;
|
||||
- break;
|
||||
- }
|
||||
+ {
|
||||
+ error (_("%s: did not find a valid archive header\n"),
|
||||
+ arch.file_name);
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
arch.next_arhdr_offset += sizeof arch.arhdr;
|
||||
|
||||
archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
|
||||
if (archive_file_size & 01)
|
||||
- ++archive_file_size;
|
||||
+ ++archive_file_size;
|
||||
|
||||
name = get_archive_member_name (&arch, &nested_arch);
|
||||
if (name == NULL)
|
||||
@@ -20395,45 +20408,45 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
}
|
||||
|
||||
if (is_thin_archive && arch.nested_member_origin == 0)
|
||||
- {
|
||||
- /* This is a proxy for an external member of a thin archive. */
|
||||
- Filedata * member_filedata;
|
||||
- char * member_file_name = adjust_relative_path
|
||||
+ {
|
||||
+ /* This is a proxy for an external member of a thin archive. */
|
||||
+ Filedata * member_filedata;
|
||||
+ char * member_file_name = adjust_relative_path
|
||||
(filedata->file_name, name, namelen);
|
||||
|
||||
free (name);
|
||||
- if (member_file_name == NULL)
|
||||
- {
|
||||
+ if (member_file_name == NULL)
|
||||
+ {
|
||||
free (qualified_name);
|
||||
- ret = FALSE;
|
||||
- break;
|
||||
- }
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- member_filedata = open_file (member_file_name);
|
||||
- if (member_filedata == NULL)
|
||||
- {
|
||||
- error (_("Input file '%s' is not readable.\n"), member_file_name);
|
||||
- free (member_file_name);
|
||||
+ member_filedata = open_file (member_file_name);
|
||||
+ if (member_filedata == NULL)
|
||||
+ {
|
||||
+ error (_("Input file '%s' is not readable.\n"), member_file_name);
|
||||
+ free (member_file_name);
|
||||
free (qualified_name);
|
||||
- ret = FALSE;
|
||||
- break;
|
||||
- }
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- archive_file_offset = arch.nested_member_origin;
|
||||
+ archive_file_offset = arch.nested_member_origin;
|
||||
member_filedata->file_name = qualified_name;
|
||||
|
||||
- if (! process_object (member_filedata))
|
||||
+ if (! process_object (member_filedata))
|
||||
ret = FALSE;
|
||||
|
||||
- close_file (member_filedata);
|
||||
- free (member_file_name);
|
||||
+ close_file (member_filedata);
|
||||
+ free (member_file_name);
|
||||
free (qualified_name);
|
||||
- }
|
||||
+ }
|
||||
else if (is_thin_archive)
|
||||
- {
|
||||
- Filedata thin_filedata;
|
||||
+ {
|
||||
+ Filedata thin_filedata;
|
||||
|
||||
- memset (&thin_filedata, 0, sizeof (thin_filedata));
|
||||
+ memset (&thin_filedata, 0, sizeof (thin_filedata));
|
||||
|
||||
/* PR 15140: Allow for corrupt thin archives. */
|
||||
if (nested_arch.file == NULL)
|
||||
@@ -20447,35 +20460,36 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
|
||||
}
|
||||
free (name);
|
||||
|
||||
- /* This is a proxy for a member of a nested archive. */
|
||||
- archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
|
||||
+ /* This is a proxy for a member of a nested archive. */
|
||||
+ archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
|
||||
|
||||
- /* The nested archive file will have been opened and setup by
|
||||
- get_archive_member_name. */
|
||||
- if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
|
||||
- {
|
||||
- error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
|
||||
+ /* The nested archive file will have been opened and setup by
|
||||
+ get_archive_member_name. */
|
||||
+ if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
|
||||
+ {
|
||||
+ error (_("%s: failed to seek to archive member.\n"),
|
||||
+ nested_arch.file_name);
|
||||
free (qualified_name);
|
||||
- ret = FALSE;
|
||||
- break;
|
||||
- }
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
thin_filedata.handle = nested_arch.file;
|
||||
thin_filedata.file_name = qualified_name;
|
||||
|
||||
- if (! process_object (& thin_filedata))
|
||||
+ if (! process_object (& thin_filedata))
|
||||
ret = FALSE;
|
||||
- }
|
||||
+ }
|
||||
else
|
||||
- {
|
||||
+ {
|
||||
free (name);
|
||||
- archive_file_offset = arch.next_arhdr_offset;
|
||||
- arch.next_arhdr_offset += archive_file_size;
|
||||
+ archive_file_offset = arch.next_arhdr_offset;
|
||||
+ arch.next_arhdr_offset += archive_file_size;
|
||||
|
||||
filedata->file_name = qualified_name;
|
||||
- if (! process_object (filedata))
|
||||
+ if (! process_object (filedata))
|
||||
ret = FALSE;
|
||||
- }
|
||||
+ }
|
||||
|
||||
free (qualified_name);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user