From: Willy Tarreau Date: Wed, 13 May 2026 08:57:29 +0000 (+0200) Subject: BUG/MEDIUM: dict: hold read lock while incrementing refcount in dict_insert X-Git-Tag: v3.4-dev12~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=de6a26e3c89da24dea2449f66e21d10a0d3a3131;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: dict: hold read lock while incrementing refcount in dict_insert In dict_insert(), the read lock on d->rwlock was released before incrementing the entry's refcount. Between the RDUNLOCK and the HA_ATOMIC_INC, another thread could call dict_entry_unref() to drop the refcount to zero, acquire the write lock, delete the entry from the tree, and free it. The subsequent HA_ATOMIC_INC would then be a use-after-free on freed memory. The fix moves the HA_ATOMIC_INC inside the read lock, matching the pattern used in stick_table.c for identical refcount-then-unlock sequences. It can be backported to the branches where this is relevant. --- diff --git a/src/dict.c b/src/dict.c index 61751eb1e..c4c54664e 100644 --- a/src/dict.c +++ b/src/dict.c @@ -84,11 +84,12 @@ struct dict_entry *dict_insert(struct dict *d, char *s) HA_RWLOCK_RDLOCK(DICT_LOCK, &d->rwlock); de = __dict_lookup(d, s); - HA_RWLOCK_RDUNLOCK(DICT_LOCK, &d->rwlock); if (de) { HA_ATOMIC_INC(&de->refcount); + HA_RWLOCK_RDUNLOCK(DICT_LOCK, &d->rwlock); return de; } + HA_RWLOCK_RDUNLOCK(DICT_LOCK, &d->rwlock); de = new_dict_entry(s); if (!de)