aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2023-11-07 16:54:44 +0100
committerMichael Matz <matz@suse.de>2023-11-09 17:42:04 +0100
commit836654b1177ab305c36fe7319f08f0ad5d4fac1b (patch)
tree8f65ea2835c51fac54fd9dcfc09b40f921c6b7aa /bfd
parent7b0c124970d0dba1703284189f09be2cbe17fa91 (diff)
downloadgdb-836654b1177ab305c36fe7319f08f0ad5d4fac1b.zip
gdb-836654b1177ab305c36fe7319f08f0ad5d4fac1b.tar.gz
gdb-836654b1177ab305c36fe7319f08f0ad5d4fac1b.tar.bz2
ld: Avoid overflows in string merging
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. bfd/ PR ld/31009 * merge.c (NEEDS_RESIZE): New macro avoiding overflow. (sec_merge_maybe_resize): Use it. (sec_merge_hash_insert): Ditto.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/merge.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/bfd/merge.c b/bfd/merge.c
index 722e665..61ffab4 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -94,6 +94,10 @@ struct sec_merge_hash
struct sec_merge_hash_entry **values;
};
+/* 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;
/* 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 = &table->table;
- if (bfdtab->count + added > table->nbuckets * 2 / 3)
+ if (NEEDS_RESIZE (bfdtab->count + added, table->nbuckets))
{
unsigned i;
unsigned long newnb = table->nbuckets * 2;
@@ -175,7 +179,7 @@ sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
uint64_t *newl;
unsigned long alloc;
- while (bfdtab->count + added > newnb * 2 / 3)
+ while (NEEDS_RESIZE (bfdtab->count + added, newnb))
{
newnb *= 2;
if (!newnb)
@@ -239,8 +243,8 @@ sec_merge_hash_insert (struct sec_merge_hash *table,
hashp->alignment = 0;
hashp->u.suffix = NULL;
hashp->next = NULL;
- // We must not need resizing, otherwise _index is wrong
- BFD_ASSERT (bfdtab->count + 1 <= 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] = (hash << 32) | (uint32_t)len;
table->values[_index] = hashp;