util/IntrusiveList: allow the last disposer to destroy the IntrusiveList

Fixes a use-after-free bug in Co::MultiAwaitable::SetReady() when the
last callback frees the Co::MultiAwaitable owner.
This commit is contained in:
Max Kellermann 2023-02-17 12:40:04 +01:00 committed by Max Kellermann
parent 2f7c19f139
commit 669cbcd25a

View File

@ -283,8 +283,18 @@ public:
}
void clear_and_dispose(Disposer<value_type> auto disposer) noexcept {
while (!empty()) {
disposer(&pop_front());
bool is_empty = empty();
while (!is_empty) {
auto *item = &pop_front();
/* by checking empty() before invoking the
disposer, it is possible for the disposer
to destroy this IntrusiveList in the last
call */
is_empty = empty();
disposer(item);
}
}