This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix illegal memory access parsing a corrupt ELF file.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=be22c732bf873e0c7e8a08564c97cafdfcf153bb

commit be22c732bf873e0c7e8a08564c97cafdfcf153bb
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Mar 14 14:45:32 2019 +0000

    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:
---
 bfd/ChangeLog |  8 ++++++++
 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]