[PATCH] Reject compressed sections exceding 4 GiB on LLP64 machines
Fangrui Song
i@maskray.me
Tue Jun 3 03:30:52 GMT 2025
On Mon, Jun 2, 2025 at 8:22 PM Rui Ueyama <rui314@gmail.com> wrote:
>
> On second thought, it’s probably better to teach the linkers to emit
> multiple zlib streams into compressed sections if the total length
> exceeds 4 GiB, rather than rejecting compressed sections
> unconditionally on the consumer side when their size exceeds 4 GiB?
Agreed. Perhaps split the input into multiple chunks or call the
compress API in a loop.
Ideally, someone will implement parallel compression, like what you
did for mold :)
> On Tue, Jun 3, 2025 at 11:16 AM Rui Ueyama <ruiu@cs.stanford.edu> wrote:
> >
> > 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>
> > ---
> > bfd/compress.c | 15 +++++++++++----
> > 1 file changed, 11 insertions(+), 4 deletions(-)
> >
> > diff --git a/bfd/compress.c b/bfd/compress.c
> > index 4f92455dbd6..99b24f7368e 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,15 @@ 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_zstd
> > + && (sec->size >= ULONG_MAX || uncompressed_size >= ULONG_MAX))
> > + {
> > + 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);
> > --
> > 2.43.0
> >
More information about the Binutils
mailing list