From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1123) id 4EA163858D35; Thu, 9 Nov 2023 16:44:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4EA163858D35 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Michael Matz To: bfd-cvs@sourceware.org Subject: [binutils-gdb] ld: Avoid overflows in string merging X-Act-Checkin: binutils-gdb X-Git-Author: Michael Matz X-Git-Refname: refs/heads/master X-Git-Oldrev: 7b0c124970d0dba1703284189f09be2cbe17fa91 X-Git-Newrev: 836654b1177ab305c36fe7319f08f0ad5d4fac1b Message-Id: <20231109164451.4EA163858D35@sourceware.org> Date: Thu, 9 Nov 2023 16:44:51 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Nov 2023 16:44:51 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D836654b1177a= b305c36fe7319f08f0ad5d4fac1b commit 836654b1177ab305c36fe7319f08f0ad5d4fac1b Author: Michael Matz Date: Tue Nov 7 16:54:44 2023 +0100 ld: Avoid overflows in string merging =20 as the bug report shows we had an overflow in the test if hash table resizing is needed. Reorder the expression to avoid that. There's still a bug somewhere in gracefully handling failure in resizing (e.g. out of memory), but this pushes the boundary for that occurring somewhen into the future and immediately helps the reporter. =20 bfd/ =20 PR ld/31009 * merge.c (NEEDS_RESIZE): New macro avoiding overflow. (sec_merge_maybe_resize): Use it. (sec_merge_hash_insert): Ditto. Diff: --- bfd/merge.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bfd/merge.c b/bfd/merge.c index 722e6659486..61ffab4d706 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -94,6 +94,10 @@ struct sec_merge_hash struct sec_merge_hash_entry **values; }; =20 +/* True when given NEWCOUNT and NBUCKETS indicate that the hash table needs + resizing. */ +#define NEEDS_RESIZE(newcount, nbuckets) ((newcount) > (nbuckets) / 3 * 2) + struct sec_merge_sec_info; =20 /* Information per merged blob. This is the unit of merging and is @@ -167,7 +171,7 @@ static bool sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added) { struct bfd_hash_table *bfdtab =3D &table->table; - if (bfdtab->count + added > table->nbuckets * 2 / 3) + if (NEEDS_RESIZE (bfdtab->count + added, table->nbuckets)) { unsigned i; unsigned long newnb =3D table->nbuckets * 2; @@ -175,7 +179,7 @@ sec_merge_maybe_resize (struct sec_merge_hash *table, u= nsigned added) uint64_t *newl; unsigned long alloc; =20 - while (bfdtab->count + added > newnb * 2 / 3) + while (NEEDS_RESIZE (bfdtab->count + added, newnb)) { newnb *=3D 2; if (!newnb) @@ -239,8 +243,8 @@ sec_merge_hash_insert (struct sec_merge_hash *table, hashp->alignment =3D 0; hashp->u.suffix =3D NULL; hashp->next =3D NULL; - // We must not need resizing, otherwise _index is wrong - BFD_ASSERT (bfdtab->count + 1 <=3D table->nbuckets * 2 / 3); + // We must not need resizing, otherwise the estimation was wrong + BFD_ASSERT (!NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets)); bfdtab->count++; table->key_lens[_index] =3D (hash << 32) | (uint32_t)len; table->values[_index] =3D hashp;