CVE-2026-14119
Overview
Background
- `SDP_ELEMENT_DATA`
- a Windows Bluetooth SDP structure that is a tagged union carrying an
SDP_TYPE typediscriminant alongside adataunion whose active member depends on that type. - `SDP_TYPE_SEQUENCE`
- the
SDP_TYPEvalue indicating the element is a container sequence, meaning thedata.sequenceunion member (valuepointer andlength) is the valid interpretation. - `BluetoothSdpGetContainerElementData`
- a Windows API that walks the child elements of an SDP container, taking the sequence’s
valuebuffer andlengthas input. - Type confusion
- a class of bug where memory belonging to one union variant is interpreted as another, so raw bytes are misread as an unrelated pointer/length pair.
Root Cause Analysis
The enclosing function (named AdvanceToSdpType in the commit message; the name does not appear in the @@ hunk itself) received an SDP_ELEMENT_DATA value in sequence_data and immediately read sequence_data.data.sequence.value and sequence_data.data.sequence.length to pass into BluetoothSdpGetContainerElementData, without first confirming that sequence_data.type was actually SDP_TYPE_SEQUENCE. Because SDP_ELEMENT_DATA is a tagged union, reading the data.sequence members when the discriminant indicates some other type reinterprets whatever bytes occupy that union (for example an integer, UUID, or string variant) as a buffer pointer and length.
The patch adds an early if (sequence_data.type != SDP_TYPE_SEQUENCE) { return false; } guard that runs before any data.sequence access, so a non-sequence element now cleanly fails instead of being misinterpreted. This tightens the code by enforcing the union’s discriminant invariant prior to dereferencing its members.
data.sequence) without checking the discriminant (type); the fix restores the invariant by validating type == SDP_TYPE_SEQUENCE before the union member is ever read.Attack Path
- Deliver crafted SDP data A malicious or malfunctioning remote Bluetooth device advertises a service record whose SDP element tree contains an element that is not a real sequence where the parser expects one.
- Reach the unchecked access
Chrome’s Windows SDP parsing calls into the enclosing function with an
SDP_ELEMENT_DATAwhosetypeis notSDP_TYPE_SEQUENCE, and the pre-patch code proceeds straight tosequence_data.data.sequence.value/.length. - Trigger type confusion
The wrong union variant’s bytes are handed to
BluetoothSdpGetContainerElementDataas avaluepointer andlength, causing the API to treat attacker-influenced data as a container buffer descriptor. - Memory disclosure or corruption (inferred) Misinterpreting arbitrary union bytes as a pointer/length pair can lead to out-of-bounds reads or further parsing of attacker-controlled memory, but the diff does not demonstrate a concrete primitive.
Impact Assessment
(inferred). Preconditions include Bluetooth being active and the victim processing the malicious device’s SDP data.Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdevice/bluetooth/bluetooth_service_record_win.cc |
modified |
Files Changed
device/bluetooth/bluetooth_service_record_win.cc
Audit Directions
- Tagged-union discriminant checksAudit every access to
SDP_ELEMENT_DATA::data(and similar tagged unions) to confirm the correspondingtype/discriminant is validated first before the member is read. - External Bluetooth/HID parsingReview other Windows Bluetooth API wrappers that consume remotely supplied SDP or descriptor data for pointer/length fields extracted without type verification.
- Container-walk entry pointsTrace all callers of
BluetoothSdpGetContainerElementDataand analogous container APIs to ensure the buffer descriptor passed in originates from a verified sequence element.
Patch
From 064b1ed634c2e0972ff071e4c740fdfc7f62fd2f Mon Sep 17 00:00:00 2001 From: Matt Reynolds <[email protected]> Date: Wed, 20 May 2026 14:04:05 -0700 Subject: [PATCH] bluetooth: Check union type before SDP_ELEMENT_DATA access AdvanceToSdpType unsafely accesses an SDP_ELEMENT_DATA object's data field without first checking its SDP_TYPE. This CL prevents the access if the type is not SDP_TYPE_SEQUENCE. Bug: 513775483 Change-Id: I7f0555c497048b73f822127946d6c2e059db097c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7861521 Reviewed-by: Alvin Ji <[email protected]> Commit-Queue: Matt Reynolds <[email protected]> Cr-Commit-Position: refs/heads/main@{#1633821} --- diff --git a/device/bluetooth/bluetooth_service_record_win.cc b/device/bluetooth/bluetooth_service_record_win.cc index 14936214..6761488 100644 --- a/device/bluetooth/bluetooth_service_record_win.cc +++ b/device/bluetooth/bluetooth_service_record_win.cc @@ -24,6 +24,9 @@ SDP_TYPE type, HBLUETOOTH_CONTAINER_ELEMENT* element, SDP_ELEMENT_DATA* sdp_data) { + if (sequence_data.type != SDP_TYPE_SEQUENCE) { + return false; + } while (ERROR_SUCCESS == BluetoothSdpGetContainerElementData( sequence_data.data.sequence.value, sequence_data.data.sequence.length,
Original Bug Report
Potential Arbitrary Memory Read in Device Service via Bluetooth SDP Type Confusion on Windows
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: A potential type confusion vulnerability in BluetoothServiceRecordWin allows a paired Bluetooth device to trigger an arbitrary memory read in the Chromium Device Service process on Windows. The issue arises from a failure to validate the data type of Service Discovery Protocol (SDP) elements before accessing union-mapped fields, allowing attacker-controlled integers to be misinterpreted as memory addresses.
Affected files:
device/bluetooth/bluetooth_service_record_win.ccdevice/bluetooth/bluetooth_task_manager_win.ccdevice/bluetooth/bluetooth_device_win.ccservices/device/serial/serial_port_manager_impl.cccontent/browser/serial/serial_service.cc
Estimated timestamp from git blame: Unknown (Google3 checkout)
Summary
A potential type confusion vulnerability has been identified in the handling of Bluetooth Service Discovery Protocol (SDP) records within the Chromium Device Service on Windows. The vulnerability exists in device/bluetooth/bluetooth_service_record_win.cc, where the code fails to verify the type discriminant of an SDP_ELEMENT_DATA structure before accessing its union members. On 64-bit systems, this leads to union punning where an attacker-controlled integer can be misinterpreted as a memory pointer, potentially leading to an arbitrary memory read or a process crash.
Root Cause Analysis
In device/bluetooth/bluetooth_service_record_win.cc, the constructor for BluetoothServiceRecordWin retrieves SDP attributes using the Windows API BluetoothSdpGetAttributeValue. The resulting SDP_ELEMENT_DATA structure contains a type field and a data union.
// device/bluetooth/bluetooth_service_record_win.cc:148-152
SDP_ELEMENT_DATA uuid_data;
if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue(
blob_data, blob_size, kUuidId, &uuid_data)) {
ExtractUuid(uuid_data, &uuid_);
}
The ExtractUuid function passes this data to AdvanceToSdpType, which immediately accesses the sequence member of the data union without checking if the type is actually SDP_TYPE_SEQUENCE:
// device/bluetooth/bluetooth_service_record_win.cc:23-31
bool AdvanceToSdpType(const SDP_ELEMENT_DATA& sequence_data, ... ) {
while (ERROR_SUCCESS == BluetoothSdpGetContainerElementData(
sequence_data.data.sequence.value,
sequence_data.data.sequence.length,
element,
sdp_data)) { ... }
}
On 64-bit Windows, the data.uint128 member (16 bytes) aliases the data.sequence structure, which contains an 8-byte LPBYTE value pointer and a 4-byte ULONG length. If a malicious Bluetooth device provides an SDP attribute encoded as a UINT128, the first 8 bytes of that integer will be reinterpreted as the value pointer in AdvanceToSdpType. This causes BluetoothSdpGetContainerElementData to attempt to parse memory at an arbitrary, attacker-controlled address.
Potential Impact
The Device Service on Windows typically runs as an unsandboxed utility process (kNoSandbox). An arbitrary memory read in this process could allow an attacker to:
- Information Leak: Exfiltrate memory contents. If the bytes at the target address can be successfully parsed as an SDP UUID element, the value is stored in the service record and can be read by a malicious webpage via
SerialPort.getInfo().bluetoothServiceClassIdin the Web Serial API. - Denial of Service: Trigger a crash of the Device Service by providing an invalid or unmapped memory address, affecting all hardware-related functionality in Chrome (Serial, HID, USB, etc.).
Suggested Potential Trigger Steps
- An attacker-controlled Bluetooth Classic device is configured to return a UINT128 for SDP attribute ID 1 (ServiceClassIDList).
- The attacker-controlled device is paired with a victim’s Windows machine.
- The victim visits a site that triggers Bluetooth device enumeration (e.g., via
navigator.serial.getPorts()). - Chrome’s Device Service polls the device’s SDP records, triggering the type confusion and subsequent arbitrary memory access.
Suggested Fix
The functions ExtractUuid and ExtractChannels should verify that the type field of the SDP_ELEMENT_DATA returned by BluetoothSdpGetAttributeValue matches the expected type (SDP_TYPE_UUID, SDP_TYPE_SEQUENCE, etc.) before further processing. Additionally, AdvanceToSdpType should include a check to ensure sequence_data.type is a valid container type (e.g., SDP_TYPE_SEQUENCE or SDP_TYPE_ALTERNATIVE) before accessing the data.sequence union member.
Evaluated with Chrome root at commit: 1a8d40fc44df2088d5945c0bf53584038aa1614a
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.