diff options
author | Nick Clifton <nickc@redhat.com> | 2019-03-14 14:45:32 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2019-03-14 14:45:32 +0000 |
commit | be22c732bf873e0c7e8a08564c97cafdfcf153bb (patch) | |
tree | 779aef5992f5920439e815d320be7f2038ace442 /bfd | |
parent | 3b336828de914a39741339b5341b88aa003d7225 (diff) | |
download | gdb-be22c732bf873e0c7e8a08564c97cafdfcf153bb.zip gdb-be22c732bf873e0c7e8a08564c97cafdfcf153bb.tar.gz gdb-be22c732bf873e0c7e8a08564c97cafdfcf153bb.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elflink.c | 29 |
2 files changed, 34 insertions, 3 deletions
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 <nickc@redhat.com> + + 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 <sudi.das@arm.com> * 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); |