Skip to content

Commit

Permalink
Stop using explicit BitMapObjectPool.
Browse files Browse the repository at this point in the history
There were only two consumers (the retrans table and exchanges) left, which both
used to fail unit tests if using ObjectPool due to use-after-free.

One of those tests is now fixed; the other is fixed in this PR.  So we can move
to using ObjectPool everywhere.

Fixes #14509
Fixes #14446
  • Loading branch information
bzbarsky-apple committed Jun 28, 2022
1 parent cba92c0 commit 440a727
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/app/CommandSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ CHIP_ERROR CommandSender::SendGroupCommandRequest(const SessionHandle & session)

ReturnErrorOnFailure(SendInvokeRequest());

// Exchange is gone now, since it closed itself on successful send.
mpExchangeCtx = nullptr;

Close();
return CHIP_NO_ERROR;
}
Expand Down
9 changes: 8 additions & 1 deletion src/app/WriteClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ CHIP_ERROR WriteClient::SendWriteRequest()

System::PacketBufferHandle data = mChunks.PopHead();

if (!mChunks.IsNull() && mpExchangeCtx->IsGroupExchangeContext())
bool isGroupWrite = mpExchangeCtx->IsGroupExchangeContext();
if (!mChunks.IsNull() && isGroupWrite)
{
// Reject this request if we have more than one chunk (mChunks is not null after PopHead()), and this is a group
// exchange context.
Expand All @@ -434,6 +435,12 @@ CHIP_ERROR WriteClient::SendWriteRequest()

// kExpectResponse is ignored by ExchangeContext in case of groupcast
ReturnErrorOnFailure(mpExchangeCtx->SendMessage(MsgType::WriteRequest, std::move(data), SendMessageFlags::kExpectResponse));
if (isGroupWrite)
{
// Exchange is closed now, since there are no group responses. Drop our
// ref to it.
mpExchangeCtx = nullptr;
}
MoveToState(State::AwaitingResponse);
return CHIP_NO_ERROR;
}
Expand Down
2 changes: 1 addition & 1 deletion src/messaging/ExchangeMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class DLL_EXPORT ExchangeManager : public SessionMessageDelegate

FabricIndex mFabricIndex = 0;

BitMapObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> mContextPool;
ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> mContextPool;

SessionManager * mSessionManager;
ReliableMessageMgr mReliableMessageMgr;
Expand Down
2 changes: 1 addition & 1 deletion src/messaging/ReliableMessageMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ReliableMessageMgr::RetransTableEntry::~RetransTableEntry()
ec->SetMessageNotAcked(false);
}

ReliableMessageMgr::ReliableMessageMgr(BitMapObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool) :
ReliableMessageMgr::ReliableMessageMgr(ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool) :
mContextPool(contextPool), mSystemLayer(nullptr)
{}

Expand Down
6 changes: 3 additions & 3 deletions src/messaging/ReliableMessageMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class ReliableMessageMgr
including both successfully and failure send. */
};

ReliableMessageMgr(BitMapObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool);
ReliableMessageMgr(ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool);
~ReliableMessageMgr();

void Init(chip::System::Layer * systemLayer);
Expand Down Expand Up @@ -177,7 +177,7 @@ class ReliableMessageMgr
#endif // CHIP_CONFIG_TEST

private:
BitMapObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & mContextPool;
ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & mContextPool;
chip::System::Layer * mSystemLayer;

/* Placeholder function to run a function for all exchanges */
Expand All @@ -193,7 +193,7 @@ class ReliableMessageMgr
void TicklessDebugDumpRetransTable(const char * log);

// ReliableMessageProtocol Global tables for timer context
BitMapObjectPool<RetransTableEntry, CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE> mRetransTable;
ObjectPool<RetransTableEntry, CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE> mRetransTable;
};

} // namespace Messaging
Expand Down
7 changes: 5 additions & 2 deletions src/messaging/tests/TestReliableMessageProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1569,6 +1569,9 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext)
// We now have just the received message waiting for an ack.
NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);

// And receiver still has no ack pending.
NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending());

// Reset various state so we can measure things again.
mockReceiver.IsOnMessageReceivedCalled = false;
mockReceiver.mReceivedPiggybackAck = false;
Expand All @@ -1594,8 +1597,8 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
NL_TEST_ASSERT(inSuite, mockReceiver.mReceivedPiggybackAck);

// And that receiver has no ack pending.
NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending());
// At this point all our exchanges and reliable message contexts should be
// dead, so we can't test anything about their state.

// And that there are no un-acked messages left.
NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
Expand Down

0 comments on commit 440a727

Please sign in to comment.