From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by sourceware.org (Postfix) with ESMTPS id F05403858D38 for ; Thu, 10 Nov 2022 10:11:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F05403858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-x1030.google.com with SMTP id m14-20020a17090a3f8e00b00212dab39bcdso4326644pjc.0 for ; Thu, 10 Nov 2022 02:11:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=JUDrplmO8OGXDHc1IDelADnHALH6dj/5YDNZszCtcC8=; b=n254hlV3ICSdUZ0Ug6Nzrbd4HpSO9cO72RRt5S0A9kNv2lfqZ/9fsxJ6VFXLqW6QAh t8QaQOtSvts/IAxmm9GDPhlCuF+Fwn6ZHqtJYqmiJw8aGVF+WVu5UCs3wn/3rI8+jIdz ykNrbgqpD1BwjxCn+huRct6hWlRq0+eAP92mOg61Jn1k46sp0pJ8PJ3q6h2diCV2FFTT kTVShmrATLie6FHnGxwFnGaUHDIt4oq5+eENBNIFg27jFiN6UiuAEwfJMokUbx1IWG9R olnf6cTxDUFuxvdNC+VQCHhO3DLMqt29i6OChUDaoKGrzIRBtYwpjnu14enbj6lKk1FF 7eJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JUDrplmO8OGXDHc1IDelADnHALH6dj/5YDNZszCtcC8=; b=8QpyVZZvzK++ots/SDTEB7foVJjBY4KLsyc6GMJcnFBcHPkbCjBpLXBLHOkDs/QkYr twWAtfw3pmjCpVSG3XIPPVXTANv+MS0DlH14jKgkxEses158oy1eMot0ZMMAPSJUAikk qbJeSoriMcctkbZOe2JYrYWz6WVw2EacuJ7Tp5JaMeLKX78Gyc89b7Fg6usuv+kr0GIi LL/AUv2PHCW6RlLzSzOjtgTl7DQJjpuBmJvmBx6sBJvMaXehx4jD/BXdwD5ni9XyLgeF NeZWeq6ZzN+IlDO5VLK4fxm3MotmYdb1mMepxxIcyoWcScGHpVxntzUW1VrPqWDe3WgS sesw== X-Gm-Message-State: ACrzQf3tknT9mt12APOe7LKGHkIXUc/p5P/psuWhQDBHySvXBipwRim6 bi4rdE6GsyJ+ZM3taUufJkh5f33VyL4= X-Google-Smtp-Source: AMsMyM7PellN4ns32QUbR8be/Kukvbb6H/u8cj7IG2Gw2RXSP/3YKlg5CzMJG2EfuEVATJOjsyrKXw== X-Received: by 2002:a17:902:d386:b0:187:190f:6ac7 with SMTP id e6-20020a170902d38600b00187190f6ac7mr56778507pld.170.1668075118394; Thu, 10 Nov 2022 02:11:58 -0800 (PST) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id c11-20020a170902d48b00b00178a9b193cfsm10923470plg.140.2022.11.10.02.11.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Nov 2022 02:11:57 -0800 (PST) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 5945A11403AC; Thu, 10 Nov 2022 20:41:55 +1030 (ACDT) Date: Thu, 10 Nov 2022 20:41:55 +1030 From: Alan Modra To: binutils@sourceware.org Subject: Sanity check reloc count in get_reloc_upper_bound Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: The idea here is the stop tools from allocating up to 32G per section for the arelent pointer array, only to find a little later that the section reloc count was fuzzed. This usually doesn't hurt much (on systems that allow malloc overcommit) except when compiled with asan. We already do this for ELF targets, and while fixing the logic recently I decided other targets ought to do the same. * elf64-sparc.c (elf64_sparc_get_reloc_upper_bound): Sanity check section reloc count against file size. * mach-o.c (bfd_mach_o_get_reloc_upper_bound): Likewise. * aoutx.h (get_reloc_upper_bound): Likewise, and don't duplicate check done in bfd_get_reloc_upper_bound. * pdp11.c (get_reloc_upper_bound): Likewise. * coffgen.c (coff_get_reloc_upper_bound): Likewise. diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 4aed23426ca..61ea9f7ce04 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2485,13 +2485,7 @@ NAME (aout, canonicalize_reloc) (bfd *abfd, long NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) { - bfd_size_type count; - - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } + size_t count, raw; if (asect->flags & SEC_CONSTRUCTOR) count = asect->reloc_count; @@ -2507,11 +2501,21 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) return -1; } - if (count >= LONG_MAX / sizeof (arelent *)) + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return (count + 1) * sizeof (arelent *); } diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 3e0fbc6184f..aab41c34ec7 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1976,19 +1976,25 @@ coff_get_normalized_symtab (bfd *abfd) long coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) { - if (bfd_get_format (abfd) != bfd_object) + size_t count, raw; + + count = asect->reloc_count; + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, bfd_coff_relsz (abfd), &raw)) { - bfd_set_error (bfd_error_invalid_operation); + bfd_set_error (bfd_error_file_too_big); return -1; } -#if SIZEOF_LONG == SIZEOF_INT - if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + if (!bfd_write_p (abfd)) { - bfd_set_error (bfd_error_file_too_big); - return -1; + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } } -#endif - return (asect->reloc_count + 1L) * sizeof (arelent *); + return (count + 1) * sizeof (arelent *); } asymbol * diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index e9f03cf8e3a..fb4483dcd17 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -37,14 +37,25 @@ static long elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) { -#if SIZEOF_LONG == SIZEOF_INT - if (sec->reloc_count >= LONG_MAX / 2 / sizeof (arelent *)) + size_t count, raw; + + count = sec->reloc_count; + if (count >= LONG_MAX / 2 / sizeof (arelent *) + || _bfd_mul_overflow (count, sizeof (Elf64_External_Rela), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } -#endif - return (sec->reloc_count * 2L + 1) * sizeof (arelent *); + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + return (count * 2 + 1) * sizeof (arelent *); } static long diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 5279343768c..664ff44a8e7 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -1407,17 +1407,27 @@ bfd_mach_o_write_dyld_info (bfd *abfd, bfd_mach_o_load_command *command) } long -bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, - asection *asect) +bfd_mach_o_get_reloc_upper_bound (bfd *abfd, asection *asect) { -#if SIZEOF_LONG == SIZEOF_INT - if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + size_t count, raw; + + count = asect->reloc_count; + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, BFD_MACH_O_RELENT_SIZE, &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } -#endif - return (asect->reloc_count + 1L) * sizeof (arelent *); + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + return (count + 1) * sizeof (arelent *); } /* In addition to the need to byte-swap the symbol number, the bit positions diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 9ef63cc311c..de9c8690e20 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -2125,13 +2125,7 @@ NAME (aout, canonicalize_reloc) (bfd *abfd, long NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) { - bfd_size_type count; - - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } + size_t count, raw; if (asect->flags & SEC_CONSTRUCTOR) count = asect->reloc_count; @@ -2147,11 +2141,21 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) return -1; } - if (count >= LONG_MAX / sizeof (arelent *)) + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return (count + 1) * sizeof (arelent *); } -- Alan Modra Australia Development Lab, IBM