CVE-2026-49933 AI-generated analysis
platform/packages/modules/Bluetooth, system/gd/hci (GD HCI layer, MsftExtensionManager / Microsoft vendor extension)
Default-initializes MsftExtensionManager::impl::scanning_callbacks_ to nullptr and adds a null check in handle_le_monitor_device_event, so a MSFT LE monitor device vendor event received before the scanning callbacks are registered is dropped instead of invoking a virtual method through an indeterminate pointer.
Root cause
In system/gd/hci/msft.cc the member `ScanningCallback* scanning_callbacks_` of `struct MsftExtensionManager::impl` was declared without an initializer, so it held an indeterminate value until it was set later. `handle_le_monitor_device_event` called `scanning_callbacks_->OnTrackAdvFoundLost(...)` with no null check whenever the event's monitor state was 0x00 or 0x01. Per the commit message, a controller that sends an MSFT_LE_MONITOR_DEVICE_EVENT during stack bring-up triggers a virtual call through the uninitialized pointer. The commit message says this could lead to control-flow hijack or denial of service in the privileged bluetooth process.
How the fix works
- system/gd/hci/msft.cc, struct MsftExtensionManager::impl member list: `ScanningCallback* scanning_callbacks_;` becomes `ScanningCallback* scanning_callbacks_{nullptr};`, so the pointer has a defined null value until registration.
- system/gd/hci/msft.cc, MsftExtensionManager::impl::handle_le_monitor_device_event: after the existing `log::assert_that(view.IsValid(), ...)`, a new early return `if (scanning_callbacks_ == nullptr) { log::warn("scanning_callbacks_ is null, dropping Microsoft vendor event."); return; }` is added before any use of the pointer.
- Same function: the monitor-state check is inverted into an early return (`if (state != 0x00 && state != 0x01) { warn; return; }`). The AdvertisingFilterOnFoundOnLostInfo population and the `scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info)` call move to straight-line code after both guards. The accepted states (0x00, 0x01) are unchanged. Because the null check comes first, an event with an invalid state that arrives while the pointer is null now logs the null warning instead of the invalid-state warning.
Completeness
- Covers the only dereference of scanning_callbacks_ visible in the diff (handle_le_monitor_device_event). Both the declaration and the use site are fixed.
- The fix is a null guard only. It does not change when or how scanning_callbacks_ is registered, and it does not gate event handling on bring-up having completed. The registration path is not shown in the material.
- Other impl members visible in the Android 16 diff context (msft_adv_monitor_add_cb_, msft_adv_monitor_remove_cb_, msft_adv_monitor_enable_cb_) are not touched. Their types and initialization state are not shown, so the material does not show whether they need similar treatment.
- handle_rssi_event is a stub that only logs and is unaffected.
Behavior changes
- A MSFT_LE_MONITOR_DEVICE_EVENT that arrives while no ScanningCallback is registered is now dropped and the warning "scanning_callbacks_ is null, dropping Microsoft vendor event." is logged. The event is not delivered.
- Accepted monitor states and the payload passed to OnTrackAdvFoundLost are unchanged. The invalid-state warning text is unchanged.
Per major
- Android 14: Not listed by the bulletin (not affected per the bulletin). At android-security-14.0.0_r30, 7/8 lines of the patched region are present. This ratio alone does not show whether the fix is present. The material includes no fix commit for 14.
- Android 15: Not listed by the bulletin (not affected per the bulletin). At android-security-15.0.0_r18, 8/8 lines of the patched region are present. This ratio alone does not show whether the fix is present. The material includes no fix commit for 15.
- Android 16: Same fix: commit 3d959c922924 in android-security-16.0.0_r8 (cherry-pick of d6505b430477, Change-Id I044a3cf62559a9e758c4d0f5d89525ae4574c57f). It modifies only system/gd/hci/msft.cc (+16/-9). At android-security-16.0.0_r9, 7/8 lines of the patched region are present, and the code context there shows the fixed function.
- Android 17: Same fix: commit 1af205db6af0 in android-security-17.0.0_r1 with an identical function body change. Only hunk offsets and the surrounding member list differ. On 17 the member declaration follows hal_, hci_layer_ and msft_ at about line 347. On 16 it follows the msft_adv_monitor_*_cb_ members at about line 318. At android-security-17.0.0_r2, 7/8 lines are present.
Unknowns
- Where and when scanning_callbacks_ is set (the registration function is not in the material), and whether the registration order relative to MsftExtensionManager start is adjusted elsewhere.
- Whether the 16-qpr2 branch listed as affected received this change (no commit for it is included).
- Types and initialization of the neighboring msft_adv_monitor_*_cb_ members, and whether a premature event can reach them.
- Whether Android 14/15 contain the vulnerable or the fixed code. The partial line-match ratios do not settle this, and the bulletin does not list them.
- Whether handle_msft_events can run before msft_.prefix is populated. The material shows the prefix loop but not where prefix is set or when the event handler is registered.
- Whether a regression test accompanies the change (the commit says only 'built and atest locally').