Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInformation leak in Bluetooth
DescriptionInformation leak in Bluetooth
ComponentBluetooth
Bug ClassLogic Error
Tracker500484520
Fix commitee79c0611ff7 (chromium/src) +19/-20
CISA KEVNot listed
CreditedGoogle
Disclosed2026-08-25

Changed Functions

FunctionChangeNotes
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.mm
  • device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
  • device/bluetooth/bluetooth_remote_gatt_service_mac.mm
From ee79c0611ff70932f2672da3d580b2fe69b7b8d0 Mon Sep 17 00:00:00 2001
From: Rob Pitkin <robpitkin@google.com>
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 <mattreynolds@chromium.org>
Commit-Queue: Rob Pitkin <robpitkin@chromium.org>
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.