From 5d41cee816c1d6104beaee863539462474fbe3df Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 31 Jan 2023 22:36:59 -0500 Subject: [PATCH] WeakReferenceable: Clear fUseCount when it is 1. Otherwise, if there are remaining weak references, they could potentially try to acquire the object and trigger a use-after-free. --- headers/private/shared/WeakReferenceable.h | 2 ++ src/kits/shared/WeakReferenceable.cpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/headers/private/shared/WeakReferenceable.h b/headers/private/shared/WeakReferenceable.h index ed2a2e1efb..950a0071ee 100644 --- a/headers/private/shared/WeakReferenceable.h +++ b/headers/private/shared/WeakReferenceable.h @@ -30,6 +30,8 @@ public: void GetUnchecked(); private: + friend class BWeakReferenceable; + int32 fUseCount; BWeakReferenceable* fObject; }; diff --git a/src/kits/shared/WeakReferenceable.cpp b/src/kits/shared/WeakReferenceable.cpp index b9ca0cd6c2..bf2ebb67c8 100644 --- a/src/kits/shared/WeakReferenceable.cpp +++ b/src/kits/shared/WeakReferenceable.cpp @@ -79,7 +79,10 @@ BWeakReferenceable::BWeakReferenceable() BWeakReferenceable::~BWeakReferenceable() { - if (fPointer->UseCount() != 0 && fPointer->UseCount() != 1) { + if (fPointer->UseCount() == 1) + atomic_test_and_set(&fPointer->fUseCount, 0, 1); + + if (fPointer->UseCount() != 0) { char message[256]; snprintf(message, sizeof(message), "deleting referenceable object %p with " "reference count (%" B_PRId32 ")", this, fPointer->UseCount());