]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add assertion failure when adding to hashmap when iterating
authorOndřej Surý <ondrej@isc.org>
Sat, 16 Sep 2023 06:32:54 +0000 (08:32 +0200)
committerOndřej Surý <ondrej@isc.org>
Tue, 19 Sep 2023 09:18:04 +0000 (11:18 +0200)
When iterating the table, we can't add new nodes to the hashmap because
we can't assure that we are not adding the new node before the iterator.

This also applies to rehashing - which might be triggered by both
isc_hashmap_add() and isc_hashmap_delete(), but not
isc_hashmap_iter_delcurrent_next().

lib/isc/hashmap.c

index a8e635a96953340fab01f717d580a5644a75e212..1fa5460770dab0067bafbb1ed5d8cad99dc9e379 100644 (file)
@@ -87,6 +87,7 @@ struct isc_hashmap {
        isc_mem_t *mctx;
        size_t count;
        hashmap_table_t tables[HASHMAP_NUM_TABLES];
+       uint_fast32_t iterators;
 };
 
 struct isc_hashmap_iter {
@@ -350,6 +351,9 @@ hashmap_rehash_one(isc_hashmap_t *hashmap) {
        hashmap_node_t *oldtable = hashmap->tables[oldidx].table;
        hashmap_node_t node;
 
+       /* Don't rehash when iterating */
+       INSIST(hashmap->iterators == 0);
+
        /* Find first non-empty node */
        while (hashmap->hiter < oldsize && oldtable[hashmap->hiter].key == NULL)
        {
@@ -502,6 +506,8 @@ hashmap_add(isc_hashmap_t *hashmap, const uint32_t hashval,
        hashmap_node_t *current = NULL;
        uint32_t pos;
 
+       INSIST(hashmap->iterators == 0);
+
        hash = isc_hash_bits32(hashval, hashmap->tables[idx].hashbits);
 
        /* Initialize the node to be store to 'node' */
@@ -599,6 +605,8 @@ isc_hashmap_iter_create(isc_hashmap_t *hashmap, isc_hashmap_iter_t **iterp) {
                .hindex = hashmap->hindex,
        };
 
+       hashmap->iterators++;
+
        *iterp = iter;
 }
 
@@ -613,6 +621,9 @@ isc_hashmap_iter_destroy(isc_hashmap_iter_t **iterp) {
        *iterp = NULL;
        hashmap = iter->hashmap;
        isc_mem_put(hashmap->mctx, iter, sizeof(*iter));
+
+       INSIST(hashmap->iterators > 0);
+       hashmap->iterators--;
 }
 
 static isc_result_t