[RFC] PR 34481 arbitrary limit on decompressed size of .dwo files

Alan Modra amodra@gmail.com
Thu Aug 27 13:20:54 GMT 2026


This is what I'm about to commit.

int aaaa..a;  where 'a' is repeated a million times, produces a
-g -gsplit-dwarf -gz .dwo file of only 2200 bytes.  This might be a
silly testcase, but it demonstrates the ten times file size limit when
decompressing .debug_str.dwo is easily exceeded.

	PR 26946
	PR 28834
	PR 34481
bfd/
	* section.c (bfd_section_size_insane): Do not attempt to sanity
	check compressed sections.
binutils/
	* readelf.c (uncompress_section_contents): Do not limit uncompressed
	section size.  Remove now unused file_size param.  Adjust callers.

diff --git a/bfd/section.c b/bfd/section.c
index 457486b0f89..fb2cc830dbd 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -1765,23 +1765,7 @@ bfd_section_size_insane (bfd *abfd, asection *sec)
 
   if (sec->compress_status == DECOMPRESS_SECTION_ZSTD
       || sec->compress_status == DECOMPRESS_SECTION_ZLIB)
-    {
-      /* PR26946, PR28834: Sanity check compress header uncompressed
-	 size against the original file size, and check that the
-	 compressed section can be read from file.  We choose an
-	 arbitrary uncompressed size of 10x the file size, rather than
-	 a compress ratio.  The reason being that compiling
-	 "int aaa..a;" with "a" repeated enough times can result in
-	 compression ratios without limit for .debug_str, whereas such
-	 a file will usually also have the enormous symbol
-	 uncompressed in .symtab.  */
-     if (size / 10 > filesize)
-       {
-	 bfd_set_error (bfd_error_bad_value);
-	 return true;
-       }
-     size = sec->compressed_size;
-    }
+    size = sec->compressed_size;
 
   if ((ufile_ptr) sec->filepos > filesize || size > filesize - sec->filepos)
     {
diff --git a/binutils/readelf.c b/binutils/readelf.c
index b5ccc675af6..aa472947cde 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -16597,8 +16597,7 @@ static bool
 uncompress_section_contents (bool              is_zstd,
 			     unsigned char **  buffer,
 			     uint64_t          uncompressed_size,
-			     uint64_t *        size,
-			     uint64_t          file_size)
+			     uint64_t *        size)
 {
   uint64_t compressed_size = *size;
   unsigned char *compressed_buffer = *buffer;
@@ -16606,16 +16605,6 @@ uncompress_section_contents (bool              is_zstd,
   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)
@@ -16732,7 +16721,7 @@ maybe_expand_or_relocate_section (Elf_Internal_Shdr *  section,
       if (uncompressed_size)
 	{
 	  if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
-					   &new_size, filedata->file_size))
+					   &new_size))
 	    {
 	      *decomp_buf = start;
 	      section_size = new_size;
@@ -17315,7 +17304,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
       if (uncompressed_size)
 	{
 	  if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
-					   &size, filedata->file_size))
+					   &size))
 	    {
 	      /* Free the compressed buffer, update the section buffer
 		 and the section size if uncompress is successful.  */

-- 
Alan Modra


More information about the Binutils mailing list