Chrome · Bluetooth
CVE-2026-79001
Logic Error in Bluetooth
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
weak_ptr_factory_device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm |
modified | |
discovery_pending_count_device/bluetooth/bluetooth_remote_gatt_service_mac.mm |
modified |
Files Changed
device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mmdevice/bluetooth/bluetooth_remote_gatt_descriptor_mac.mmdevice/bluetooth/bluetooth_remote_gatt_service_mac.mm
Patch
From ee79c0611ff70932f2672da3d580b2fe69b7b8d0 Mon Sep 17 00:00:00 2001 From: Rob Pitkin <[email protected]> Date: Mon, 13 Jul 2026 09:57:17 -0700 Subject: [PATCH] Prevent macOS WebBluetooth GATT identifiers from leaking heap pointers On macOS, BluetoothRemoteGattServiceMac, BluetoothRemoteGattCharacteristicMac, and BluetoothRemoteGattDescriptorMac constructed GATT identifiers using Objective-C format string stringWithFormat:@"%s-%p". Because macOS Chromium uses PartitionAlloc Everywhere (PA-E), formatting %p embeds 64-bit virtual heap addresses into the identifier string. When these strings are sent over Mojo IPC to the renderer process, a compromised renderer could read these pointer addresses to map browser heap layout and bypass ASLR. Replace %p with base::UnguessableToken::Create().ToString().c_str() to ensure cryptographically unguessable, stateless, thread-safe uniqueness without leaking browser heap layout. Also update operator<< logging to log GetIdentifier(). TAG=agy CONV=60ab6f7d-f6e6-4bf5-8b14-067aefab4126 Bug: 500484520 Change-Id: Ic69106765f6a13c6746601321b50a13336f67412 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8025918 Reviewed-by: Matt Reynolds <[email protected]> Commit-Queue: Rob Pitkin <[email protected]> Cr-Commit-Position: refs/heads/main@{#1661181} --- diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm index b2ba785..20a2cfe2 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.mm @@ -9,9 +9,11 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/notimplemented.h" +#include "base/strings/strcat.h" #include "base/strings/sys_string_conversions.h" #import "base/task/single_thread_task_runner.h" #include "base/task/single_thread_task_runner.h" +#include "base/unguessable_token.h" #include "device/bluetooth/bluetooth_device_mac.h" #include "device/bluetooth/bluetooth_gatt_notify_session.h" #include "device/bluetooth/bluetooth_low_energy_adapter_apple.h" @@ -80,9 +82,8 @@ weak_ptr_factory_(this) { uuid_ = BluetoothLowEnergyAdapterApple::BluetoothUUIDWithCBUUID( [cb_characteristic_ UUID]); - identifier_ = base::SysNSStringToUTF8( - [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), - cb_characteristic_]); + identifier_ = base::StrCat({uuid_.canonical_value(), "-", + base::UnguessableToken::Create().ToString()}); } BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { @@ -483,9 +484,7 @@ static_cast<const BluetoothRemoteGattServiceMac*>( characteristic.GetService()); return out << "<BluetoothRemoteGattCharacteristicMac " - << characteristic.GetUUID().canonical_value() << "/" - << &characteristic - << ", service: " << service_mac->GetUUID().canonical_value() << "/" - << service_mac << ">"; + << characteristic.GetIdentifier() + << ", service: " << service_mac->GetIdentifier() << ">"; } } // namespace device. diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm index 169dab0..dbc25d7 100644 --- a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm @@ -7,9 +7,11 @@ #import "base/apple/foundation_util.h" #include "base/functional/bind.h" #include "base/notimplemented.h" +#include "base/strings/strcat.h" #include "base/strings/sys_string_conversions.h" #import "base/task/single_thread_task_runner.h" #include "base/task/single_thread_task_runner.h" +#include "base/unguessable_token.h" #include "device/bluetooth/bluetooth_low_energy_adapter_apple.h" #import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" @@ -50,9 +52,8 @@ : gatt_characteristic_(characteristic), cb_descriptor_(descriptor) { uuid_ = BluetoothLowEnergyAdapterApple::BluetoothUUIDWithCBUUID( [cb_descriptor_ UUID]); - identifier_ = base::SysNSStringToUTF8( - [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), - cb_descriptor_]); + identifier_ = base::StrCat({uuid_.canonical_value(), "-", + base::UnguessableToken::Create().ToString()}); } std::string BluetoothRemoteGattDescriptorMac::GetIdentifier() const { @@ -188,10 +189,9 @@ static_cast<const BluetoothRemoteGattCharacteristicMac*>( descriptor.GetCharacteristic()); return out << "<BluetoothRemoteGattDescriptorMac " - << descriptor.GetUUID().canonical_value() << "/" << &descriptor - << ", characteristic: " - << characteristic_mac->GetUUID().canonical_value() << "/" - << characteristic_mac << ">"; + << descriptor.GetIdentifier() + << ", characteristic: " << characteristic_mac->GetIdentifier() + << ">"; } } // namespace device. diff --git a/device/bluetooth/bluetooth_remote_gatt_service_mac.mm b/device/bluetooth/bluetooth_remote_gatt_service_mac.mm index 1a51be0..81900c1 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_mac.mm +++ b/device/bluetooth/bluetooth_remote_gatt_service_mac.mm @@ -12,7 +12,9 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/notimplemented.h" +#include "base/strings/strcat.h" #include "base/strings/sys_string_conversions.h" +#include "base/unguessable_token.h" #include "device/bluetooth/bluetooth_low_energy_adapter_apple.h" #include "device/bluetooth/bluetooth_low_energy_device_mac.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" @@ -30,8 +32,8 @@ discovery_pending_count_(0) { uuid_ = BluetoothLowEnergyAdapterApple::BluetoothUUIDWithCBUUID([service_ UUID]); - identifier_ = base::SysNSStringToUTF8([NSString - stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), service_]); + identifier_ = base::StrCat({uuid_.canonical_value(), "-", + base::UnguessableToken::Create().ToString()}); } BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {} @@ -195,10 +197,8 @@ const BluetoothRemoteGattServiceMac& service) { const BluetoothLowEnergyDeviceMac* bluetooth_device_mac_ = static_cast<const BluetoothLowEnergyDeviceMac*>(service.GetDevice()); - return out << "<BluetoothRemoteGattServiceMac " - << service.GetUUID().canonical_value() << "/" << &service - << ", device: " << bluetooth_device_mac_->GetAddress() << "/" - << bluetooth_device_mac_ << ">"; + return out << "<BluetoothRemoteGattServiceMac " << service.GetIdentifier() + << ", device: " << bluetooth_device_mac_->GetAddress() << ">"; } } // namespace device
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