]> git.ipfire.org Git - thirdparty/bind9.git/commit
Dispatch ratelimiter events under the lock
authorOndřej Surý <ondrej@isc.org>
Thu, 30 Apr 2026 05:39:23 +0000 (07:39 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 30 Apr 2026 08:16:32 +0000 (10:16 +0200)
commit4d465f4fa58abb79b90d9019900e7d543fb511ea
tree1e546d4008b91c53ad2a5f11173056cd11bf1bdc
parentbf7ee390bad0ce22d977ec7f5dffdc1dd7daaaae
Dispatch ratelimiter events under the lock

isc__ratelimiter_tick() and isc_ratelimiter_shutdown() each pulled
events out of rl->pending into a function-local list, dropped the
mutex, and then iterated.  ISC_LIST_APPEND leaves the link in the
LINKED state, so a concurrent isc_ratelimiter_dequeue() saw an
event as still queued, called ISC_LIST_UNLINK against rl->pending —
which patched the prev/next of the local list — and freed the
event before dispatch finished, producing either an INSIST in the
unlink macro or a use-after-free in the dispatch loop.

isc_async_run() is a non-blocking wfcq enqueue, so there is no
benefit to dropping the mutex around it.  Unlink each event and
hand it to isc_async_run() while still holding rl->lock; the
existing ISC_LINK_LINKED check in dequeue then correctly
distinguishes "still queued and cancellable" from "already taken".

Assisted-by: Claude:claude-opus-4-7
lib/isc/ratelimiter.c