Chrome · Bluetooth
CVE-2026-14032
UAF in Bluetooth
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdevice/bluetooth/bluetooth_socket_mac.mm |
modified |
Files Changed
device/bluetooth/bluetooth_socket_mac.mm
Patch
From 375096a7dd434f3fa2a5cff6a8c71c3f3827da83 Mon Sep 17 00:00:00 2001 From: Alvin Ji <[email protected]> Date: Fri, 22 May 2026 20:15:45 -0700 Subject: [PATCH] bluetooth: Fix potential browser-process UAF in socket listeners Due to an Apple framework bug (FB13705522), IOBluetooth holds an unsafe_unretained pointer and may dispatch late callbacks to freed listeners after unregistration. This CL fixes the UAF by clearing back-pointers and posting a keep-alive block to the main queue, ensuring the listener safely outlives any pending OS notifications. Bug: 495783474 Change-Id: I79497e722159320158bb411fcb15f99066d7ca0e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7833747 Reviewed-by: Matt Reynolds <[email protected]> Commit-Queue: Alvin Ji <[email protected]> Cr-Commit-Position: refs/heads/main@{#1635359} --- diff --git a/device/bluetooth/bluetooth_socket_mac.mm b/device/bluetooth/bluetooth_socket_mac.mm index 60b5df97..2348f81a 100644 --- a/device/bluetooth/bluetooth_socket_mac.mm +++ b/device/bluetooth/bluetooth_socket_mac.mm @@ -122,6 +122,7 @@ channelID:(BluetoothRFCOMMChannelID)channelID; - (void)rfcommChannelOpened:(IOBluetoothUserNotification*)notification channel:(IOBluetoothRFCOMMChannel*)rfcommChannel; +- (void)stopListening; @end @@ -150,8 +151,26 @@ [_rfcommNewChannelNotification unregister]; } +- (void)stopListening { + [_rfcommNewChannelNotification unregister]; + _socket = nullptr; + + // Keep self alive for a brief period to allow any already-enqueued + // notifications on the main run loop to fire safely (and become no-ops + // since _socket is now null) rather than hitting a deallocated object. + // See FB13705522. + __strong auto strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + (void)strongSelf; + }); +} + - (void)rfcommChannelOpened:(IOBluetoothUserNotification*)notification channel:(IOBluetoothRFCOMMChannel*)rfcommChannel { + if (!_socket) { + return; + } + if (notification != _rfcommNewChannelNotification) { // This case is reachable if there are pre-existing RFCOMM channels open at // the time that the listener is created. In that case, each existing @@ -184,6 +203,7 @@ psm:(BluetoothL2CAPPSM)psm; - (void)l2capChannelOpened:(IOBluetoothUserNotification*)notification channel:(IOBluetoothL2CAPChannel*)l2capChannel; +- (void)stopListening; @end @@ -212,8 +232,26 @@ [_l2capNewChannelNotification unregister]; } +- (void)stopListening { + [_l2capNewChannelNotification unregister]; + _socket = nullptr; + + // Keep self alive for a brief period to allow any already-enqueued + // notifications on the main run loop to fire safely (and become no-ops + // since _socket is now null) rather than hitting a deallocated object. + // See FB13705522. + __strong auto strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + (void)strongSelf; + }); +} + - (void)l2capChannelOpened:(IOBluetoothUserNotification*)notification channel:(IOBluetoothL2CAPChannel*)l2capChannel { + if (!_socket) { + return; + } + if (notification != _l2capNewChannelNotification) { // This case is reachable if there are pre-existing L2CAP channels open at // the time that the listener is created. In that case, each existing @@ -1001,7 +1039,9 @@ [service_record_ removeServiceRecord]; service_record_ = nil; + [rfcomm_connection_listener_ stopListening]; rfcomm_connection_listener_ = nil; + [l2cap_connection_listener_ stopListening]; l2cap_connection_listener_ = nil; // Destroying the listener above prevents the callback delegate from being
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page