Skip to content

Commit

Permalink
Fix crash if commissionee drops PASE session before AddNOC. (#21121) (#…
Browse files Browse the repository at this point in the history
…21167)

Several changes here:

1. Fix ReleaseCommissioneeDevice so it does not leave mDeviceBeingCommissioned
   dangling.
2. Ensure that we have null-checks for mDeviceBeingCommissioned before all
   uses, in case it got nulled out by StopPairing or the like while some async
   operation was in flight.  This changes:
   * DeviceCommissioner::DisarmDone
   * DeviceCommissioner::OnDeviceAttestationInformationVerification
3. Remove kSessionEstablishmentTimeout so we don't have a random hardcoded
   timeout partway through commissioning.

Fixes #21106
Fixes #14650

Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
woody-apple and bzbarsky-apple authored Jul 25, 2022
1 parent 94a8ead commit 45fa932
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 34 deletions.
44 changes: 14 additions & 30 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ using namespace chip::Encoding;
using namespace chip::Protocols::UserDirectedCommissioning;
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

constexpr uint32_t kSessionEstablishmentTimeout = 40 * kMillisecondsPerSecond;

DeviceController::DeviceController()
{
mState = State::NotInitialized;
Expand Down Expand Up @@ -546,6 +544,10 @@ void DeviceCommissioner::ReleaseCommissioneeDevice(CommissioneeDeviceProxy * dev
{
mDeviceInPASEEstablishment = nullptr;
}
if (mDeviceBeingCommissioned == device)
{
mDeviceBeingCommissioned = nullptr;
}
}

CHIP_ERROR DeviceCommissioner::GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** out_device)
Expand Down Expand Up @@ -759,9 +761,6 @@ CHIP_ERROR DeviceCommissioner::Commission(NodeId remoteDeviceId)

ChipLogProgress(Controller, "Commission called for node ID 0x" ChipLogFormatX64, ChipLogValueX64(remoteDeviceId));

mSystemState->SystemLayer()->StartTimer(chip::System::Clock::Milliseconds32(kSessionEstablishmentTimeout),
OnSessionEstablishmentTimeoutCallback, this);

mDefaultCommissioner->SetOperationalCredentialsDelegate(mOperationalCredentialsDelegate);
if (device->IsSecureConnected())
{
Expand Down Expand Up @@ -859,9 +858,6 @@ void DeviceCommissioner::RendezvousCleanup(CHIP_ERROR status)

void DeviceCommissioner::OnSessionEstablishmentError(CHIP_ERROR err)
{
// PASE session establishment failure.
mSystemState->SystemLayer()->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);

if (mPairingDelegate != nullptr)
{
mPairingDelegate->OnStatusUpdate(DevicePairingDelegate::SecurePairingFailed);
Expand Down Expand Up @@ -977,6 +973,12 @@ void DeviceCommissioner::OnDeviceAttestationInformationVerification(void * conte
MATTER_TRACE_EVENT_SCOPE("OnDeviceAttestationInformationVerification", "DeviceCommissioner");
DeviceCommissioner * commissioner = reinterpret_cast<DeviceCommissioner *>(context);

if (!commissioner->mDeviceBeingCommissioned)
{
ChipLogError(Controller, "Device attestation verification result received when we're not commissioning a device");
return;
}

if (result != AttestationVerificationResult::kSuccess)
{
CommissioningDelegate::CommissioningReport report;
Expand Down Expand Up @@ -1363,8 +1365,6 @@ CHIP_ERROR DeviceCommissioner::OnOperationalCredentialsProvisioningCompletion(De
ChipLogProgress(Controller, "Operational credentials provisioned on device %p", device);
VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

mSystemState->SystemLayer()->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);

if (mPairingDelegate != nullptr)
{
mPairingDelegate->OnStatusUpdate(DevicePairingDelegate::SecurePairingSuccess);
Expand Down Expand Up @@ -1395,26 +1395,6 @@ void DeviceCommissioner::CloseBleConnection()
}
#endif

void DeviceCommissioner::OnSessionEstablishmentTimeout()
{
// This is called from the session establishment timer. Please see
// https://github.com/project-chip/connectedhomeip/issues/14650
VerifyOrReturn(mState == State::Initialized);
VerifyOrReturn(mDeviceBeingCommissioned != nullptr);

StopPairing(mDeviceBeingCommissioned->GetDeviceId());

if (mPairingDelegate != nullptr)
{
mPairingDelegate->OnPairingComplete(CHIP_ERROR_TIMEOUT);
}
}

void DeviceCommissioner::OnSessionEstablishmentTimeoutCallback(System::Layer * aLayer, void * aAppState)
{
static_cast<DeviceCommissioner *>(aAppState)->OnSessionEstablishmentTimeout();
}

CHIP_ERROR DeviceCommissioner::DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter)
{
ReturnErrorOnFailure(SetUpNodeDiscovery());
Expand Down Expand Up @@ -1522,6 +1502,10 @@ void DeviceCommissioner::OnDisarmFailsafeFailure(void * context, CHIP_ERROR erro

void DeviceCommissioner::DisarmDone()
{
// If someone nulled out our mDeviceBeingCommissioned, there's nothing else
// to do here.
VerifyOrReturn(mDeviceBeingCommissioned != nullptr);

// At this point, we also want to close off the pase session so we need to re-establish
CommissioneeDeviceProxy * commissionee = FindCommissioneeDevice(mDeviceBeingCommissioned->GetDeviceId());

Expand Down
4 changes: 0 additions & 4 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,10 +677,6 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,

CHIP_ERROR LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out);

void OnSessionEstablishmentTimeout();

static void OnSessionEstablishmentTimeoutCallback(System::Layer * aLayer, void * aAppState);

/* This function sends a Device Attestation Certificate chain request to the device.
The function does not hold a reference to the device object.
*/
Expand Down

0 comments on commit 45fa932

Please sign in to comment.