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 invalid memory access attempting to read the compression header of a too-small compressed sectio


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

commit ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Feb 13 14:52:48 2017 +0000

    Fix invalid memory access attempting to read the compression header of a too-small compressed section.
    
    	PR binutils/21149
    	* readelf.c (get_compression_header): Add size parameter.  Check
    	size against sizeof compression header before attempting to
    	extract the header.
    	(process_section_headers): Pass size to get_compression_header.
    	(dump_section_as_strings): Likewise.
    	(dump_section_as_bytes): Likewise.
    	(load_specific_debug_section): Likewise.

Diff:
---
 binutils/ChangeLog | 11 +++++++++++
 binutils/readelf.c | 23 ++++++++++++++++++-----
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index ebaedcc..10140c2 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,16 @@
 2017-02-13  Nick Clifton  <nickc@redhat.com>
 
+	PR binutils/21149
+	* readelf.c (get_compression_header): Add size parameter.  Check
+	size against sizeof compression header before attempting to
+	extract the header.
+	(process_section_headers): Pass size to get_compression_header.
+	(dump_section_as_strings): Likewise.
+	(dump_section_as_bytes): Likewise.
+	(load_specific_debug_section): Likewise.
+
+2017-02-13  Nick Clifton  <nickc@redhat.com>
+
 	PR binutils/21148
 	* readelf.c (process_version_sections): Include size of auxillary
 	version information when checking for buffer overflow.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index a61befe..e6f48b4 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -5715,12 +5715,18 @@ get_elf_section_flags (bfd_vma sh_flags)
 }
 
 static unsigned int
-get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
+get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
 {
   if (is_32bit_elf)
     {
       Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
 
+      if (size < sizeof (* echdr))
+	{
+	  error (_("Compressed section is too small even for a compression header\n"));
+	  return 0;
+	}
+
       chdr->ch_type = BYTE_GET (echdr->ch_type);
       chdr->ch_size = BYTE_GET (echdr->ch_size);
       chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
@@ -5730,6 +5736,12 @@ get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
     {
       Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
 
+      if (size < sizeof (* echdr))
+	{
+	  error (_("Compressed section is too small even for a compression header\n"));
+	  return 0;
+	}
+
       chdr->ch_type = BYTE_GET (echdr->ch_type);
       chdr->ch_size = BYTE_GET (echdr->ch_size);
       chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
@@ -6311,7 +6323,7 @@ process_section_headers (FILE * file)
 		{
 		  Elf_Internal_Chdr chdr;
 
-		  (void) get_compression_header (&chdr, buf);
+		  (void) get_compression_header (&chdr, buf, sizeof (buf));
 
 		  if (chdr.ch_type == ELFCOMPRESS_ZLIB)
 		    printf ("       ZLIB, ");
@@ -12643,7 +12655,8 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
 	{
 	  Elf_Internal_Chdr chdr;
 	  unsigned int compression_header_size
-	    = get_compression_header (& chdr, (unsigned char *) start);
+	    = get_compression_header (& chdr, (unsigned char *) start,
+				      num_bytes);
 
 	  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
 	    {
@@ -12777,7 +12790,7 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
 	{
 	  Elf_Internal_Chdr chdr;
 	  unsigned int compression_header_size
-	    = get_compression_header (& chdr, start);
+	    = get_compression_header (& chdr, start, section_size);
 
 	  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
 	    {
@@ -12930,7 +12943,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
 	      return 0;
 	    }
 
-	  compression_header_size = get_compression_header (&chdr, start);
+	  compression_header_size = get_compression_header (&chdr, start, size);
 
 	  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
 	    {


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