mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:14:58 +00:00
Kernel: Lock weak pointer revocation during listed-ref-counted unref
When doing the last unref() on a listed-ref-counted object, we keep the list locked while mutating the ref count. The destructor itself is invoked after unlocking the list. This was racy with weakable classes, since their weak pointer factory still pointed to the object after we'd decided to destroy it. That opened a small time window where someone could try to strong-ref a weak pointer to an object after it was removed from the list, but just before the destructor got invoked. This patch closes the race window by explicitly revoking all weak pointers while the list is locked.
This commit is contained in:
parent
c4a0f01b02
commit
b86443f0e1
3 changed files with 7 additions and 1 deletions
|
@ -29,8 +29,12 @@ public:
|
|||
|
||||
auto callback = [&](auto& list) {
|
||||
auto new_ref_count = deref_base();
|
||||
if (new_ref_count == 0)
|
||||
if (new_ref_count == 0) {
|
||||
list.remove(const_cast<T&>(*that));
|
||||
if constexpr (requires { that->revoke_weak_ptrs(); }) {
|
||||
that->revoke_weak_ptrs();
|
||||
}
|
||||
}
|
||||
return new_ref_count;
|
||||
};
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ bool TCPSocket::unref() const
|
|||
if (deref_base())
|
||||
return false;
|
||||
table.remove(tuple());
|
||||
const_cast<TCPSocket&>(*this).revoke_weak_ptrs();
|
||||
return true;
|
||||
});
|
||||
if (did_hit_zero) {
|
||||
|
|
|
@ -26,6 +26,7 @@ bool SlavePTY::unref() const
|
|||
if (deref_base())
|
||||
return false;
|
||||
m_list_node.remove();
|
||||
const_cast<SlavePTY&>(*this).revoke_weak_ptrs();
|
||||
return true;
|
||||
});
|
||||
if (did_hit_zero) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue