asan: readelf leak in hppa_process_unwind
This extracts code reading symbol tables into a common function that tidies up after errors. I've also changed an error reporting multiple string tables to an error on multiple symbol tables. * readelf.c (get_symbols): New function. (process_relocs, ia64_process_unwind, hppa_process_unwind), (arm_process_unwind, get_symbol_for_build_attribute): Use it.
This commit is contained in:
parent
60e63c3e97
commit
28d1356774
2 changed files with 81 additions and 79 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2020-03-16 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* readelf.c (get_symbols): New function.
|
||||||
|
(process_relocs, ia64_process_unwind, hppa_process_unwind),
|
||||||
|
(arm_process_unwind, get_symbol_for_build_attribute): Use it.
|
||||||
|
|
||||||
2020-03-16 Alan Modra <amodra@gmail.com>
|
2020-03-16 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* unwind-ia64.c (unw_decode_uleb128): Prevent overlarge shifts.
|
* unwind-ia64.c (unw_decode_uleb128): Prevent overlarge shifts.
|
||||||
|
|
|
@ -6765,6 +6765,47 @@ process_section_headers (Filedata * filedata)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
|
||||||
|
Elf_Internal_Sym **symtab, unsigned long *nsyms,
|
||||||
|
char **strtab, unsigned long *strtablen)
|
||||||
|
{
|
||||||
|
*strtab = NULL;
|
||||||
|
*strtablen = 0;
|
||||||
|
*symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
|
||||||
|
|
||||||
|
if (*symtab == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (symsec->sh_link != 0)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *strsec;
|
||||||
|
|
||||||
|
if (symsec->sh_link >= filedata->file_header.e_shnum)
|
||||||
|
{
|
||||||
|
error (_("Bad sh_link in symbol table section\n"));
|
||||||
|
free (*symtab);
|
||||||
|
*symtab = NULL;
|
||||||
|
*nsyms = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strsec = filedata->section_headers + symsec->sh_link;
|
||||||
|
|
||||||
|
*strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
|
||||||
|
1, strsec->sh_size, _("string table"));
|
||||||
|
if (*strtab == NULL)
|
||||||
|
{
|
||||||
|
free (*symtab);
|
||||||
|
*symtab = NULL;
|
||||||
|
*nsyms = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*strtablen = strsec->sh_size;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
get_group_flags (unsigned int flags)
|
get_group_flags (unsigned int flags)
|
||||||
{
|
{
|
||||||
|
@ -7355,7 +7396,6 @@ process_relocs (Filedata * filedata)
|
||||||
|
|
||||||
if (rel_size)
|
if (rel_size)
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr * strsec;
|
|
||||||
int is_rela;
|
int is_rela;
|
||||||
unsigned long num_rela;
|
unsigned long num_rela;
|
||||||
|
|
||||||
|
@ -7388,22 +7428,10 @@ process_relocs (Filedata * filedata)
|
||||||
&& symsec->sh_type != SHT_DYNSYM)
|
&& symsec->sh_type != SHT_DYNSYM)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
|
if (!get_symtab (filedata, symsec,
|
||||||
|
&symtab, &nsyms, &strtab, &strtablen))
|
||||||
if (symtab == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (symsec->sh_link != 0
|
|
||||||
&& symsec->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
|
||||||
strsec = filedata->section_headers + symsec->sh_link;
|
|
||||||
|
|
||||||
strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
|
|
||||||
1, strsec->sh_size,
|
|
||||||
_("string table"));
|
|
||||||
strtablen = strtab == NULL ? 0 : strsec->sh_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_relocations (filedata, rel_offset, rel_size,
|
dump_relocations (filedata, rel_offset, rel_size,
|
||||||
symtab, nsyms, strtab, strtablen,
|
symtab, nsyms, strtab, strtablen,
|
||||||
is_rela,
|
is_rela,
|
||||||
|
@ -7804,7 +7832,6 @@ ia64_process_unwind (Filedata * filedata)
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr * sec;
|
Elf_Internal_Shdr * sec;
|
||||||
Elf_Internal_Shdr * unwsec = NULL;
|
Elf_Internal_Shdr * unwsec = NULL;
|
||||||
Elf_Internal_Shdr * strsec;
|
|
||||||
unsigned long i, unwcount = 0, unwstart = 0;
|
unsigned long i, unwcount = 0, unwstart = 0;
|
||||||
struct ia64_unw_aux_info aux;
|
struct ia64_unw_aux_info aux;
|
||||||
bfd_boolean res = TRUE;
|
bfd_boolean res = TRUE;
|
||||||
|
@ -7813,22 +7840,19 @@ ia64_process_unwind (Filedata * filedata)
|
||||||
|
|
||||||
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
if (sec->sh_type == SHT_SYMTAB
|
if (sec->sh_type == SHT_SYMTAB)
|
||||||
&& sec->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
{
|
||||||
aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
|
if (aux.symtab)
|
||||||
|
|
||||||
strsec = filedata->section_headers + sec->sh_link;
|
|
||||||
if (aux.strtab != NULL)
|
|
||||||
{
|
{
|
||||||
error (_("Multiple auxillary string tables encountered\n"));
|
error (_("Multiple symbol tables encountered\n"));
|
||||||
|
free (aux.symtab);
|
||||||
|
aux.symtab = NULL;
|
||||||
free (aux.strtab);
|
free (aux.strtab);
|
||||||
res = FALSE;
|
aux.strtab = NULL;
|
||||||
}
|
}
|
||||||
aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
|
if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
|
||||||
1, strsec->sh_size,
|
&aux.strtab, &aux.strtab_size))
|
||||||
_("string table"));
|
return FALSE;
|
||||||
aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
|
|
||||||
}
|
}
|
||||||
else if (sec->sh_type == SHT_IA_64_UNWIND)
|
else if (sec->sh_type == SHT_IA_64_UNWIND)
|
||||||
unwcount++;
|
unwcount++;
|
||||||
|
@ -8265,7 +8289,6 @@ hppa_process_unwind (Filedata * filedata)
|
||||||
{
|
{
|
||||||
struct hppa_unw_aux_info aux;
|
struct hppa_unw_aux_info aux;
|
||||||
Elf_Internal_Shdr * unwsec = NULL;
|
Elf_Internal_Shdr * unwsec = NULL;
|
||||||
Elf_Internal_Shdr * strsec;
|
|
||||||
Elf_Internal_Shdr * sec;
|
Elf_Internal_Shdr * sec;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
bfd_boolean res = TRUE;
|
bfd_boolean res = TRUE;
|
||||||
|
@ -8277,22 +8300,19 @@ hppa_process_unwind (Filedata * filedata)
|
||||||
|
|
||||||
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
if (sec->sh_type == SHT_SYMTAB
|
if (sec->sh_type == SHT_SYMTAB)
|
||||||
&& sec->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
{
|
||||||
aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
|
if (aux.symtab)
|
||||||
|
|
||||||
strsec = filedata->section_headers + sec->sh_link;
|
|
||||||
if (aux.strtab != NULL)
|
|
||||||
{
|
{
|
||||||
error (_("Multiple auxillary string tables encountered\n"));
|
error (_("Multiple symbol tables encountered\n"));
|
||||||
|
free (aux.symtab);
|
||||||
|
aux.symtab = NULL;
|
||||||
free (aux.strtab);
|
free (aux.strtab);
|
||||||
res = FALSE;
|
aux.strtab = NULL;
|
||||||
}
|
}
|
||||||
aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
|
if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
|
||||||
1, strsec->sh_size,
|
&aux.strtab, &aux.strtab_size))
|
||||||
_("string table"));
|
return FALSE;
|
||||||
aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
|
|
||||||
}
|
}
|
||||||
else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
|
else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
|
||||||
unwsec = sec;
|
unwsec = sec;
|
||||||
|
@ -9363,7 +9383,6 @@ arm_process_unwind (Filedata * filedata)
|
||||||
{
|
{
|
||||||
struct arm_unw_aux_info aux;
|
struct arm_unw_aux_info aux;
|
||||||
Elf_Internal_Shdr *unwsec = NULL;
|
Elf_Internal_Shdr *unwsec = NULL;
|
||||||
Elf_Internal_Shdr *strsec;
|
|
||||||
Elf_Internal_Shdr *sec;
|
Elf_Internal_Shdr *sec;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned int sec_type;
|
unsigned int sec_type;
|
||||||
|
@ -9393,22 +9412,19 @@ arm_process_unwind (Filedata * filedata)
|
||||||
|
|
||||||
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
|
if (sec->sh_type == SHT_SYMTAB)
|
||||||
{
|
{
|
||||||
aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
|
if (aux.symtab)
|
||||||
|
|
||||||
strsec = filedata->section_headers + sec->sh_link;
|
|
||||||
|
|
||||||
/* PR binutils/17531 file: 011-12666-0.004. */
|
|
||||||
if (aux.strtab != NULL)
|
|
||||||
{
|
{
|
||||||
error (_("Multiple string tables found in file.\n"));
|
error (_("Multiple symbol tables encountered\n"));
|
||||||
|
free (aux.symtab);
|
||||||
|
aux.symtab = NULL;
|
||||||
free (aux.strtab);
|
free (aux.strtab);
|
||||||
res = FALSE;
|
aux.strtab = NULL;
|
||||||
}
|
}
|
||||||
aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
|
if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
|
||||||
1, strsec->sh_size, _("string table"));
|
&aux.strtab, &aux.strtab_size))
|
||||||
aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (sec->sh_type == sec_type)
|
else if (sec->sh_type == sec_type)
|
||||||
unwsec = sec;
|
unwsec = sec;
|
||||||
|
@ -18836,31 +18852,11 @@ get_symbol_for_build_attribute (Filedata * filedata,
|
||||||
symsec < filedata->section_headers + filedata->file_header.e_shnum;
|
symsec < filedata->section_headers + filedata->file_header.e_shnum;
|
||||||
symsec ++)
|
symsec ++)
|
||||||
{
|
{
|
||||||
if (symsec->sh_type == SHT_SYMTAB)
|
if (symsec->sh_type == SHT_SYMTAB
|
||||||
{
|
&& get_symtab (filedata, symsec,
|
||||||
ba_cache.symtab = GET_ELF_SYMBOLS (filedata, symsec,
|
&ba_cache.symtab, &ba_cache.nsyms,
|
||||||
&ba_cache.nsyms);
|
&ba_cache.strtab, &ba_cache.strtablen))
|
||||||
|
break;
|
||||||
if (ba_cache.symtab != NULL
|
|
||||||
&& symsec->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ba_cache.filedata = filedata;
|
ba_cache.filedata = filedata;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue