diff --git a/src/app/CASEClientPool.h b/src/app/CASEClientPool.h index 79e29d3ede1ddb..99bc913793e738 100644 --- a/src/app/CASEClientPool.h +++ b/src/app/CASEClientPool.h @@ -43,7 +43,7 @@ class CASEClientPool : public CASEClientPoolDelegate void Release(CASEClient * client) override { mClientPool.ReleaseObject(client); } private: - BitMapObjectPool mClientPool; + ObjectPool mClientPool; }; }; // namespace chip diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index 421ba7e0491010..41aa33db976a6b 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -283,12 +283,12 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate, public Comman CommandHandlerInterface * mCommandHandlerList = nullptr; - BitMapObjectPool mCommandHandlerObjs; - BitMapObjectPool mTimedHandlers; + ObjectPool mCommandHandlerObjs; + ObjectPool mTimedHandlers; ObjectPool mReadHandlers; WriteHandler mWriteHandlers[CHIP_IM_MAX_NUM_WRITE_HANDLER]; reporting::Engine mReportingEngine; - BitMapObjectPool mClusterInfoPool; + ObjectPool mClusterInfoPool; ReadClient * mpActiveReadClientList = nullptr; diff --git a/src/app/OperationalDeviceProxyPool.h b/src/app/OperationalDeviceProxyPool.h index 8fed456db7998d..bfdc53d72a47ec 100644 --- a/src/app/OperationalDeviceProxyPool.h +++ b/src/app/OperationalDeviceProxyPool.h @@ -90,7 +90,7 @@ class OperationalDeviceProxyPool : public OperationalDeviceProxyPoolDelegate } private: - BitMapObjectPool mDevicePool; + ObjectPool mDevicePool; }; }; // namespace chip diff --git a/src/app/clusters/bindings/BindingManager.h b/src/app/clusters/bindings/BindingManager.h index 8456f1ace7180e..d4b9acd0bafc35 100644 --- a/src/app/clusters/bindings/BindingManager.h +++ b/src/app/clusters/bindings/BindingManager.h @@ -167,7 +167,7 @@ class BindingManager } private: - BitMapObjectPool mPendingNotificationMap; + ObjectPool mPendingNotificationMap; }; static void HandleDeviceConnected(void * context, OperationalDeviceProxy * device); diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h index ee9d86538225c4..1fa762b51236be 100644 --- a/src/app/reporting/Engine.h +++ b/src/app/reporting/Engine.h @@ -171,7 +171,7 @@ class Engine * mGlobalDirtySet is used to track the set of attribute/event paths marked dirty for reporting purposes. * */ - BitMapObjectPool mGlobalDirtySet; + ObjectPool mGlobalDirtySet; #if CONFIG_IM_BUILD_FOR_UNIT_TEST uint32_t mReservedSize = 0; diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 155914c9e82b6c..15c4e47692d9d0 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -697,7 +697,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing; bool mRunCommissioningAfterConnection = false; - BitMapObjectPool mCommissioneeDevicePool; + ObjectPool mCommissioneeDevicePool; #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable UserDirectedCommissioningServer * mUdcServer = nullptr; diff --git a/src/credentials/GroupDataProviderImpl.h b/src/credentials/GroupDataProviderImpl.h index bcb18b5ae4700d..90aea6fa10422c 100644 --- a/src/credentials/GroupDataProviderImpl.h +++ b/src/credentials/GroupDataProviderImpl.h @@ -217,12 +217,12 @@ class GroupDataProviderImpl : public GroupDataProvider chip::PersistentStorageDelegate & mStorage; bool mInitialized = false; - BitMapObjectPool mGroupInfoIterators; - BitMapObjectPool mGroupKeyIterators; - BitMapObjectPool mEndpointIterators; - BitMapObjectPool mKeySetIterators; - BitMapObjectPool mGroupSessionsIterator; - BitMapObjectPool mKeyContexPool; + ObjectPool mGroupInfoIterators; + ObjectPool mGroupKeyIterators; + ObjectPool mEndpointIterators; + ObjectPool mKeySetIterators; + ObjectPool mGroupSessionsIterator; + ObjectPool mKeyContexPool; }; } // namespace Credentials diff --git a/src/credentials/tests/TestGroupDataProvider.cpp b/src/credentials/tests/TestGroupDataProvider.cpp index 766f551fb440d0..0ac1402616d824 100644 --- a/src/credentials/tests/TestGroupDataProvider.cpp +++ b/src/credentials/tests/TestGroupDataProvider.cpp @@ -1200,12 +1200,12 @@ int Test_Setup(void * inContext) */ int Test_Teardown(void * inContext) { - chip::Platform::MemoryShutdown(); GroupDataProvider * provider = GetGroupDataProvider(); if (nullptr != provider) { provider->Finish(); } + chip::Platform::MemoryShutdown(); return SUCCESS; } diff --git a/src/inet/InetLayer.h b/src/inet/InetLayer.h index 4da18d1c0b706e..9cd28eb3f2d052 100644 --- a/src/inet/InetLayer.h +++ b/src/inet/InetLayer.h @@ -117,8 +117,8 @@ class EndPointManagerImplPool : public EndPointManager; using EndPoint = typename EndPointImpl::EndPoint; - EndPointManagerImplPool() = default; - ~EndPointManagerImplPool() { VerifyOrDie(sEndPointPool.Allocated() == 0); } + EndPointManagerImplPool() = default; + ~EndPointManagerImplPool() = default; EndPoint * CreateEndPoint() override { return sEndPointPool.CreateObject(*this); } void ReleaseEndPoint(EndPoint * endPoint) override { sEndPointPool.ReleaseObject(static_cast(endPoint)); } diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index 4c7749866a1df8..2a28850c4841b2 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -294,7 +294,16 @@ class HeapObjectPool : public internal::Statistics, public internal::PoolCommon< { public: HeapObjectPool() {} - ~HeapObjectPool() { VerifyOrDie(Allocated() == 0); } + ~HeapObjectPool() + { +#if __SANITIZE_ADDRESS__ + // Free all remaining objects so that ASAN can catch specific use-after-free cases. + ReleaseAll(); +#else // __SANITIZE_ADDRESS__ + // Verify that no live objects remain, to prevent potential use-after-free. + VerifyOrDie(Allocated() == 0); +#endif // __SANITIZE_ADDRESS__ + } template T * CreateObject(Args &&... args) diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index a6c8421f08847d..a6cfb9d1947c2e 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -96,12 +96,6 @@ CHIP_ERROR ExchangeManager::Shutdown() { mReliableMessageMgr.Shutdown(); - mContextPool.ForEachActiveObject([](auto * ec) { - // There should be no active object in the pool - VerifyOrDie(false); - return Loop::Continue; - }); - if (mSessionManager != nullptr) { mSessionManager->SetMessageDelegate(nullptr); diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index 05be52b6ef008a..b74024174d9840 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -31,6 +31,7 @@ CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioCo mIOContext = ioContext; mTransport = transport; + ReturnErrorOnFailure(PlatformMemoryUser::Init()); ReturnErrorOnFailure(mSessionManager.Init(&GetSystemLayer(), transport, &mMessageCounterManager)); ReturnErrorOnFailure(mExchangeManager.Init(&mSessionManager)); diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index cc99415e729029..210699a48098b6 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -30,11 +30,42 @@ namespace chip { namespace Test { +/** + * @brief + * Test contexts that use Platform::Memory and might call Free() on destruction can inherit from this class and call its Init(). + * Platform::MemoryShutdown() will then be called after the subclasses' destructor. + */ +class PlatformMemoryUser +{ +public: + PlatformMemoryUser() : mInitialized(false) {} + ~PlatformMemoryUser() + { + if (mInitialized) + { + chip::Platform::MemoryShutdown(); + } + } + CHIP_ERROR Init() + { + CHIP_ERROR status = CHIP_NO_ERROR; + if (!mInitialized) + { + status = chip::Platform::MemoryInit(); + mInitialized = (status == CHIP_NO_ERROR); + } + return status; + } + +private: + bool mInitialized; +}; + /** * @brief The context of test cases for messaging layer. It wil initialize network layer and system layer, and create * two secure sessions, connected with each other. Exchanges can be created for each secure session. */ -class MessagingContext +class MessagingContext : public PlatformMemoryUser { public: MessagingContext() : diff --git a/src/protocols/secure_channel/CASESessionCache.cpp b/src/protocols/secure_channel/CASESessionCache.cpp index 75cffdcfa901c6..74c1662ff09e32 100644 --- a/src/protocols/secure_channel/CASESessionCache.cpp +++ b/src/protocols/secure_channel/CASESessionCache.cpp @@ -50,7 +50,7 @@ CHIP_ERROR CASESessionCache::Add(CASESessionCachable & cachableSession) VerifyOrReturnError(mCachePool.Capacity() > 0, CHIP_NO_ERROR); // If the cache is full, get the least recently used session index and release that. - if (mCachePool.Exhausted()) + if (mCachePool.Allocated() >= kCacheSize) { mCachePool.ReleaseObject(GetLRUSession()); } diff --git a/src/protocols/secure_channel/CASESessionCache.h b/src/protocols/secure_channel/CASESessionCache.h index 96eeddfeaf4441..f4bbca22c431e1 100644 --- a/src/protocols/secure_channel/CASESessionCache.h +++ b/src/protocols/secure_channel/CASESessionCache.h @@ -37,7 +37,8 @@ class CASESessionCache CHIP_ERROR Get(const PeerId & peer, CASESessionCachable & outCachableSession); private: - BitMapObjectPool mCachePool; + static constexpr size_t kCacheSize = CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE; + ObjectPool mCachePool; CASESessionCachable * GetLRUSession(); }; diff --git a/src/transport/SessionManager.h b/src/transport/SessionManager.h index 7d30ba0f2364cf..5b4cda34960783 100644 --- a/src/transport/SessionManager.h +++ b/src/transport/SessionManager.h @@ -251,7 +251,7 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate SessionMessageDelegate * mCB = nullptr; - BitMapObjectPool, CHIP_CONFIG_MAX_SESSION_RECOVERY_DELEGATES> + ObjectPool, CHIP_CONFIG_MAX_SESSION_RECOVERY_DELEGATES> mSessionRecoveryDelegates; TransportMgrBase * mTransportMgr = nullptr; diff --git a/src/transport/UnauthenticatedSessionTable.h b/src/transport/UnauthenticatedSessionTable.h index 0b645d011a79e3..8e7cbd1ec371fb 100644 --- a/src/transport/UnauthenticatedSessionTable.h +++ b/src/transport/UnauthenticatedSessionTable.h @@ -241,7 +241,7 @@ class UnauthenticatedSessionTable return false; } - BitMapObjectPool mEntries; + ObjectPool mEntries; }; } // namespace Transport