[binutils-gdb] Reject compressed sections exceding 4 GiB on LLP64 machines

H.J. Lu hjl@sourceware.org
Wed Jun 4 06:24:50 GMT 2025


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

commit 9037efb5472bc139d3be675ea4274105faeae5b3
Author: Rui Ueyama <ruiu@cs.stanford.edu>
Date:   Tue Jun 3 11:16:02 2025 +0900

    Reject compressed sections exceding 4 GiB on LLP64 machines
    
    According to the zlib FAQ (*1), zlib does not support compressed data
    larger than 4 GiB when the compiler's long type is 32 bits. Therefore,
    we need to report an error if a zlib-compressed debug section exceeds
    4 GiB on LLP64 machines.
    
    (*1) https://zlib.net/zlib_faq.html#faq32
    
    Signed-off-by: Rui Ueyama <rui314@gmail.com>

Diff:
---
 bfd/compress.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/bfd/compress.c b/bfd/compress.c
index 4f92455dbd6..28788370210 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -521,10 +521,8 @@ decompress_contents (bool is_zstd, bfd_byte *compressed_buffer,
      buffers concatenated together, so we uncompress in a loop.  */
   do
     {
-      uLongf dst_len = (uncompressed_size > ULONG_MAX ? ULONG_MAX
-			: uncompressed_size);
-      uLong src_len = (compressed_size > ULONG_MAX ? ULONG_MAX
-		       : compressed_size);
+      uLongf dst_len = uncompressed_size;
+      uLong src_len = compressed_size;
       int rc = uncompress2 ((Bytef *) uncompressed_buffer, &dst_len,
 			    (Bytef *) compressed_buffer, &src_len);
       if (rc != Z_OK)
@@ -1009,6 +1007,16 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
       return false;
     }
 
+  /* PR28530, reject sizes unsupported by decompress_contents. zlib
+     supports only up to 4 GiB input on machines whose long is 32 bits. */
+  if (ch_type == ch_compress_zlib
+      && (sec->size != (uLong) sec->size
+	  || uncompressed_size != (uLongf) uncompressed_size))
+    {
+      bfd_set_error (bfd_error_nonrepresentable_section);
+      return false;
+    }
+
   sec->compressed_size = sec->size;
   sec->size = uncompressed_size;
   bfd_set_section_alignment (sec, uncompressed_alignment_power);


More information about the Binutils-cvs mailing list