Skip to content

Fix use-after-free segfault on BluezConnection pointer#72821

Draft
feasel0 wants to merge 3 commits into
project-chip:masterfrom
feasel0:feature/segfault-OnDiscoveredDeviceOverBle
Draft

Fix use-after-free segfault on BluezConnection pointer#72821
feasel0 wants to merge 3 commits into
project-chip:masterfrom
feasel0:feature/segfault-OnDiscoveredDeviceOverBle

Conversation

@feasel0

@feasel0 feasel0 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What is wrong

SetUpCodePairer can discover the same commissionee over BLE and UDP/DNS-SD concurrently. If a UDP PASE attempt is already in progress (mWaitingForPASE == true) when BLE discovery succeeds, the old code queued the live BluezConnection * in mDiscoveredParameters for a later retry. At that point no BLEEndPoint had been created for the connection, so the BLE layer had no endpoint associated with that pointer.

If the DUT closes the BLE link while the UDP PASE attempt is still in flight, BluezEndpoint removes the BluezConnection from its map and schedules it for deletion. BleLayer::HandleConnectionError logs that there is no endpoint for the connection error and returns, leaving the queued raw pointer untouched. When UDP PASE later fails and the pairer retries the queued BLE entry, it can pass a freed BluezConnection * into BleLayer::NewBleConnectionByObject. The resulting endpoint wraps a stale connection object, which can fail on the first write because mC1 is gone and then crash while trying to close the same freed connection.

How it was fixed

In SetUpCodePairer::OnDiscoveredDeviceOverBle, when mWaitingForPASE == true, the live connection handle is no longer stored. Instead, the pairer queues a reconnectable BLE entry: a BLE peer address plus the matched long discriminator, when one was reported. When the deferred retry runs, ConnectToDiscoveredDevice() resolves the discriminator back to the matching setup payload and fills in the setup PIN/discriminator. DeviceCommissioner::EstablishPASEConnection() then uses those parameters to call BleLayer::NewBleConnectionByDiscriminator, starting a fresh BLE scan instead of reusing the old connection object.

When mWaitingForPASE == false, the existing fast path is preserved: the live connection handle is queued and consumed immediately, creating a BLEEndPoint for the active connection instead of leaving the raw pointer dormant.

Testing

TestSetUpCodePairer.cpp gets a new test, DeferredBleDiscoveryQueuesReconnectableParams, which:

  • Sets mWaitingForPASE = true to simulate an in-flight PASE attempt
  • Calls OnDiscoveredDeviceOverBle with a representative connection object and long discriminator
  • Asserts that the enqueued entry has a BLE peer address but no ConnectionObject and no DiscoveredObject — confirming the raw pointer was not stored
  • Asserts that the long discriminator was preserved so the later retry can resolve the correct setup payload

SetUpCodePairerTestAccess is extended with GetDiscoveredParametersCount(), FrontDiscoveredParameters(), and CallOnDiscoveredDeviceOverBle() to expose the state needed by the new test without modifying production code visibility.

Issues affected

Fixes #72252

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 56.63%. Comparing base (d9d3108) to head (0cf2754).

Files with missing lines Patch % Lines
src/controller/SetUpCodePairer.cpp 83.33% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master   #72821   +/-   ##
=======================================
  Coverage   56.62%   56.63%           
=======================================
  Files        1642     1642           
  Lines      113154   113159    +5     
  Branches    13235    13234    -1     
=======================================
+ Hits        64079    64091   +12     
+ Misses      49075    49068    -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR #72821: Size comparison from d9d3108 to ac95f61

Full report (33 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, efr32, esp32, nrfconnect, psoc6, qpg, realtek, stm32, telink)
platform target config section d9d3108 ac95f61 change % change
bl602 lighting-app bl602+mfd+littlefs+rpc FLASH 1099194 1099194 0 0.0
RAM 133418 133418 0 0.0
bl702 lighting-app bl702+eth FLASH 1085744 1085744 0 0.0
RAM 109029 109029 0 0.0
bl702l contact-sensor-app bl702l+mfd+littlefs FLASH 882236 882236 0 0.0
RAM 108596 108596 0 0.0
cc13x4_26x4 lighting-app LP_EM_CC1354P10_6 FLASH 777384 777384 0 0.0
RAM 103404 103404 0 0.0
lock-ftd LP_EM_CC1354P10_6 FLASH 790136 790136 0 0.0
RAM 108684 108684 0 0.0
pump-app LP_EM_CC1354P10_6 FLASH 739392 739392 0 0.0
RAM 97612 97612 0 0.0
pump-controller-app LP_EM_CC1354P10_6 FLASH 719564 719564 0 0.0
RAM 97644 97644 0 0.0
cc32xx air-purifier CC3235SF_LAUNCHXL FLASH 569670 569670 0 0.0
RAM 205112 205112 0 0.0
lock CC3235SF_LAUNCHXL FLASH 597230 597230 0 0.0
RAM 205272 205272 0 0.0
efr32 lighting-app BRD4187C FLASH 1104716 1104716 0 0.0
RAM 135360 135360 0 0.0
lock-app BRD4187C FLASH 995184 995184 0 0.0
RAM 131292 131292 0 0.0
BRD4338a FLASH 799825 799825 0 0.0
RAM 243432 243432 0 0.0
esp32 all-clusters-app c3devkit DRAM 99556 99556 0 0.0
FLASH 1626306 1626306 0 0.0
IRAM 94776 94776 0 0.0
nrfconnect all-clusters-app nrf52840dk_nrf52840 FLASH 845892 845892 0 0.0
RAM 157923 157923 0 0.0
psoc6 all-clusters cy8ckit_062s2_43012 FLASH 1752716 1752716 0 0.0
RAM 215644 215644 0 0.0
all-clusters-minimal cy8ckit_062s2_43012 FLASH 1626564 1626564 0 0.0
RAM 211604 211604 0 0.0
light cy8ckit_062s2_43012 FLASH 1470876 1470876 0 0.0
RAM 197436 197436 0 0.0
lock cy8ckit_062s2_43012 FLASH 1504324 1504324 0 0.0
RAM 225268 225268 0 0.0
qpg lighting-app qpg6200+debug FLASH 843292 843292 0 0.0
RAM 127908 127908 0 0.0
lock-app qpg6200+debug FLASH 783064 783064 0 0.0
RAM 118840 118840 0 0.0
realtek light-switch-app rtl8777g FLASH 689984 689984 0 0.0
RAM 101880 101880 0 0.0
lighting-app rtl8777g FLASH 730320 730320 0 0.0
RAM 102052 102052 0 0.0
stm32 light STM32WB5MM-DK FLASH 478996 478996 0 0.0
RAM 141492 141492 0 0.0
telink all-devices-app tl7218x FLASH 881732 881732 0 0.0
RAM 99716 99716 0 0.0
tlsr9118bdk40d FLASH 673338 673338 0 0.0
RAM 120848 120848 0 0.0
bridge-app tl7218x FLASH 734172 734172 0 0.0
RAM 97700 97700 0 0.0
light-app-ota-compress-lzma-factory-data tl3218x FLASH 800698 800698 0 0.0
RAM 42380 42380 0 0.0
light-app-ota-compress-lzma-shell-factory-data tl7218x FLASH 845838 845838 0 0.0
RAM 101492 101492 0 0.0
light-switch-app-ota-compress-lzma-factory-data tl7218x_retention FLASH 743060 743060 0 0.0
RAM 57924 57924 0 0.0
light-switch-app-ota-compress-lzma-shell-factory-data tlsr9528a FLASH 804148 804148 0 0.0
RAM 75276 75276 0 0.0
light-switch-app-ota-factory-data tl3218x_retention FLASH 742976 742976 0 0.0
RAM 34584 34584 0 0.0
lighting-app-ota-factory-data tlsr9118bdk40d FLASH 615230 615230 0 0.0
RAM 118508 118508 0 0.0
lighting-app-ota-rpc-factory-data-4mb tlsr9518adk80d FLASH 842054 842058 4 0.0
RAM 97376 97376 0 0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Nordic][BLE] Segfault in TC_Android_Pair due to NULL C1 characteristic in BluezConnection::SendWriteRequest

1 participant