handle_dynamic_symtab can attempt to read symbol and version data from file offset 0 if the associated DT_ tags aren't found.
Fix this by only reading symbol and version data when non-zero file offsets have been found. https://sourceware.org/bugzilla/show_bug.cgi?id=32864 Suggested-by: Constantine Bytensky <cbyten...@gmail.com> Signed-off-by: Aaron Merey <ame...@redhat.com> --- src/readelf.c | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/readelf.c b/src/readelf.c index 5b0e7b47..0452977f 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3047,18 +3047,25 @@ handle_dynamic_symtab (Ebl *ebl) Elf_Data *verdef_data = NULL; Elf_Data *verneed_data = NULL; - symdata = elf_getdata_rawchunk ( - ebl->elf, offs[i_symtab], - gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM); - symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz], - ELF_T_BYTE); - versym_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF); + if (offs[i_symtab] != 0) + symdata = elf_getdata_rawchunk ( + ebl->elf, offs[i_symtab], + gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM); + + if (offs[i_strtab] != 0) + symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz], + ELF_T_BYTE); + + if (offs[i_versym] != 0) + versym_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF); /* Get the verneed_data without vernaux. */ - verneed_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed), - ELF_T_VNEED); + if (offs[i_verneed] != 0) + verneed_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed), + ELF_T_VNEED); + size_t vernauxnum = 0; size_t vn_next_offset = 0; @@ -3071,14 +3078,18 @@ handle_dynamic_symtab (Ebl *ebl) } /* Update the verneed_data to include the vernaux. */ - verneed_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verneed], - (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), ELF_T_VNEED); + if (offs[i_verneed] != 0) + verneed_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verneed], + (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), + ELF_T_VNEED); /* Get the verdef_data without verdaux. */ - verdef_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef), - ELF_T_VDEF); + if (offs[i_verdef] != 0) + verdef_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef), + ELF_T_VDEF); + size_t verdauxnum = 0; size_t vd_next_offset = 0; @@ -3091,9 +3102,10 @@ handle_dynamic_symtab (Ebl *ebl) } /* Update the verdef_data to include the verdaux. */ - verdef_data = elf_getdata_rawchunk ( - ebl->elf, offs[i_verdef], - (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF); + if (offs[i_verdef] != 0) + verdef_data = elf_getdata_rawchunk ( + ebl->elf, offs[i_verdef], + (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF); unsigned int nsyms = (unsigned int)syments; process_symtab (ebl, nsyms, 0, 0, 0, symdata, versym_data, symstrdata, -- 2.49.0