public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] Fix an attempt to allocate an overlarge amount of memory when decoding a corrupt ELF format file.
@ 2023-04-11 14:30 Nick Clifton
  0 siblings, 0 replies; only message in thread
From: Nick Clifton @ 2023-04-11 14:30 UTC (permalink / raw)
  To: bfd-cvs

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

commit 45f5fe468b23c92b571756ec72b6a9c7be034074
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Apr 11 15:30:02 2023 +0100

    Fix an attempt to allocate an overlarge amount of memory when decoding a corrupt ELF format file.
    
      PR 30311
      * readelf.c (uncompress_section_contents): Check for a suspiciously large uncompressed size.

Diff:
---
 binutils/ChangeLog |  6 ++++++
 binutils/readelf.c | 27 +++++++++++++++++++++------
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 0794bed00d3..f81f2308651 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2023-04-11  Nick Clifton  <nickc@redhat.com>
+
+	PR 30311
+	* readelf.c (uncompress_section_contents): Check for a
+	suspiciously large uncompressed size.
+
 2023-03-30  Nick Clifton  <nickc@redhat.com>
 
 	PR 30284
diff --git a/binutils/readelf.c b/binutils/readelf.c
index a47cb0eda0a..b872876a8b6 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15268,15 +15268,30 @@ get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
 /* Uncompresses a section that was compressed using zlib/zstd, in place.  */
 
 static bool
-uncompress_section_contents (bool is_zstd, unsigned char **buffer,
-			     uint64_t uncompressed_size, uint64_t *size)
+uncompress_section_contents (bool              is_zstd,
+			     unsigned char **  buffer,
+			     uint64_t          uncompressed_size,
+			     uint64_t *        size,
+			     uint64_t          file_size)
 {
   uint64_t compressed_size = *size;
   unsigned char *compressed_buffer = *buffer;
-  unsigned char *uncompressed_buffer = xmalloc (uncompressed_size);
+  unsigned char *uncompressed_buffer = NULL;
   z_stream strm;
   int rc;
 
+  /* Similar to _bfd_section_size_insane() in the BFD library we expect an
+     upper limit of ~10x compression.  Any compression larger than that is
+     thought to be due to fuzzing of the compression header.  */
+  if (uncompressed_size > file_size * 10)
+    {
+      error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
+	       uncompressed_size);
+      goto fail;
+    }
+
+  uncompressed_buffer = xmalloc (uncompressed_size);
+  
   if (is_zstd)
     {
 #ifdef HAVE_ZSTD
@@ -15406,7 +15421,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
       if (uncompressed_size)
 	{
 	  if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
-					   &new_size))
+					   &new_size, filedata->file_size))
 	    num_bytes = new_size;
 	  else
 	    {
@@ -15629,7 +15644,7 @@ dump_section_as_bytes (Elf_Internal_Shdr *section,
       if (uncompressed_size)
 	{
 	  if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
-					   &new_size))
+					   &new_size, filedata->file_size))
 	    {
 	      section_size = new_size;
 	    }
@@ -16061,7 +16076,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
       if (uncompressed_size)
 	{
 	  if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
-					   &size))
+					   &size, filedata->file_size))
 	    {
 	      /* Free the compressed buffer, update the section buffer
 		 and the section size if uncompress is successful.  */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-11 14:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-11 14:30 [binutils-gdb] Fix an attempt to allocate an overlarge amount of memory when decoding a corrupt ELF format file Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).