From: Nick Clifton Date: Thu, 14 Mar 2019 14:45:32 +0000 (+0000) Subject: Fix illegal memory access parsing a corrupt ELF file. X-Git-Tag: binutils-2_33~1842 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=be22c732bf873e0c7e8a08564c97cafdfcf153bb;p=external%2Fbinutils.git Fix illegal memory access parsing a corrupt ELF file. PR 24332 * elflink.c (elf_link_add_object_symbols): Add new local variable extversym_end. Initialise it to point to the end of the version symbol table, if present. Check it when initialising and updating the ever pointer. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 540f737..447eb70 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2019-03-14 Nick Clifton + + PR 24332 + * elflink.c (elf_link_add_object_symbols): Add new local variable + extversym_end. Initialise it to point to the end of the version + symbol table, if present. Check it when initialising and updating + the ever pointer. + 2019-03-13 Sudakshina Das * elfnn-aarch64.c (PLT_PAC_ENTRY_SIZE, PLT_PAC_SMALL_ENTRY_SIZE): New. diff --git a/bfd/elflink.c b/bfd/elflink.c index e50c0e4..3ac58da 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3872,6 +3872,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) struct elf_link_hash_entry **sym_hash; bfd_boolean dynamic; Elf_External_Versym *extversym = NULL; + Elf_External_Versym *extversym_end = NULL; Elf_External_Versym *ever; struct elf_link_hash_entry *weaks; struct elf_link_hash_entry **nondeflt_vers = NULL; @@ -4297,13 +4298,14 @@ error_free_dyn: Elf_Internal_Shdr *versymhdr; versymhdr = &elf_tdata (abfd)->dynversym_hdr; - extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size); + amt = versymhdr->sh_size; + extversym = (Elf_External_Versym *) bfd_malloc (amt); if (extversym == NULL) goto error_free_sym; - amt = versymhdr->sh_size; if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0 || bfd_bread (extversym, amt, abfd) != amt) goto error_free_vers; + extversym_end = extversym + (amt / sizeof (* extversym)); } } @@ -4378,7 +4380,20 @@ error_free_dyn: } weaks = NULL; - ever = extversym != NULL ? extversym + extsymoff : NULL; + if (extversym == NULL) + ever = NULL; + else if (extversym + extsymoff < extversym_end) + ever = extversym + extsymoff; + else + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: invalid version offset %lx (max %lx)"), + abfd, (long) extsymoff, + (long) (extversym_end - extversym) / sizeof (* extversym)); + bfd_set_error (bfd_error_bad_value); + goto error_free_vers; + } + for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) @@ -4562,6 +4577,14 @@ error_free_dyn: else iver.vs_vers = 0; } + else if (ever >= extversym_end) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: not enough version information"), + abfd); + bfd_set_error (bfd_error_bad_value); + goto error_free_vers; + } else _bfd_elf_swap_versym_in (abfd, ever, &iver);