Closed Bug 2022162 (CVE-2026-6764) Opened 7 months ago Closed 7 months ago

Heap buffer overflow in Dualshock4Remapper::ProcessTouchData via malicious USB HID device

Categories

(Core :: DOM: Device Interfaces, defect, P2)

Firefox 148
defect

Tracking

()

RESOLVED FIXED
151 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 150+ fixed
firefox149 --- wontfix
firefox150 + fixed
firefox151 + fixed

People

(Reporter: fb.secresearch, Assigned: jstutte)

References

Details

(Keywords: csectype-bounds, reporter-external, sec-moderate, Whiteboard: [adv-main150+][adv-esr140.10+])

Attachments

(1 file, 3 external files)

18.72 KB, application/zip
Details
Attached file f7b_poc.zip —

User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36

Steps to reproduce:

  1. Create a USB HID gadget impersonating a DualShock 4 controller (VID=054c, PID=05c4) with 8-byte HID reports using a valid gamepad descriptor. See attached setup_gadget_multisize.sh.
  2. Connect the device to a Windows machine running Firefox 148.0.
  3. Send HID reports at 60Hz (send_reports.py --size 8).
  4. Navigate to a page that calls navigator.getGamepads() or registers a gamepadconnected listener (see attached poc.html). No permission dialog is shown.

Tested with Firefox 148.0 Release (Windows 11) and ASAN Nightly (win64-asan-opt).

Attached files:
setup_gadget_multisize.sh creates the USB gadget (Linux configfs).
send_reports.py sends HID reports with configurable size.
poc.html reads and displays the leaked OOB heap bytes via GamepadTouch (requires dom.gamepad.extensions.multitouch=true to visualize the data, but the OOB read in the parent process occurs regardless of this pref).

Any USB composite device (keyboard, charger, etc.) can include a secondary HID interface with Sony's VID/PID to trigger this. The device does not need to look like a game controller.

Actual results:

ProcessTouchData() in GamepadRemapping.cpp:488 reads rawData[35] through rawData[42] using hardcoded offsets without checking the buffer length. With 8-byte reports this reads 26 bytes past the end of a 49-byte heap allocation in the parent process.

ASAN crashes immediately:

==2868==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x11fe452bdd8b
READ of size 1 at 0x11fe452bdd8b thread T135
    #0 in mozilla::dom::Dualshock4Remapper::ProcessTouchData
       GamepadRemapping.cpp:488
    #1 in GamepadWindowProc WindowsGamepad.cpp:1023

0x11fe452bdd8b is located 26 bytes after 49-byte region
  [0x11fe452bdd40,0x11fe452bdd71)

The function receives a void* without length. WindowsGamepad.cpp:1023 has raw->data.hid.dwSizeHid available but does not pass it.

Affected VID/PIDs (GamepadRemapping.cpp:2158-2160): 054c:05c4, 054c:09cc, 054c:0ba0.
Affected on Windows and macOS. Linux does not call ProcessTouchData.

When dom.gamepad.extensions.multitouch is enabled, the OOB bytes become readable from JavaScript through GamepadTouch.position[]. The attached log_8.txt shows 2569 unique readings from a single session, containing HTTP headers, internal resource:// URLs, file paths, and token fragments from the parent process heap.

Expected results:

ProcessTouchData should receive the buffer length and check len >= 43 before reading touch offsets. On Windows, dwSizeHid is already available in HandleRawInput. On macOS, report_len is passed to ReportChanged but not forwarded. Reports shorter than 43 bytes should skip touch processing.

Group: firefox-core-security → dom-core-security
Component: Untriaged → DOM: Device Interfaces
Product: Firefox → Core
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-moderate

The severity field is not set for this bug.
:cmartin, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(cmartin)
Duplicate of this bug: 2025404
Attached file (secure) —
Assignee: nobody → jstutte
Status: NEW → ASSIGNED

Thank you for the detailed report. The OOB read is confirmed and we have a patch in progress (D290082).

A few notes from our Claude assessment on severity and the information disclosure claim (to be checked):

OOB read — confirmed

ProcessTouchData receives a raw void* with no length and reads hardcoded offsets 35–42. On Windows, the caller has dwSizeHid available but doesn't pass it. On macOS, the caller only enforces an upper bound on report length, not a lower bound. This is a real bug that should be fixed.

Information disclosure — overstated

The claim that OOB heap bytes are readable from JavaScript via GamepadTouch.position[] deserves closer scrutiny. The OOB bytes go through bit-field extraction (e.g. ((rawData[37] & 0xf) << 8) | rawData[36]) producing a 12-bit integer, which is then passed to NormalizeTouch — a linear mapping onto [-1.0, 1.0] over a 1920x942 range. While the linear transform is technically reversible, you recover at most ~12 bits per coordinate per report, not raw heap bytes. The touchId field leaks 7 bits per touch point.

The report claims "2569 unique readings containing HTTP headers, internal resource:// URLs, file paths, and token fragments." Reconstructing meaningful strings from 12-bit quantized floats at this rate would be extremely difficult in practice. The practical information leakage is much lower than the report suggests.

Preconditions

Requires physical USB access to the target machine.
Requires a web page actively using the Gamepad API.
dom.gamepad.extensions.multitouch must be enabled (default: false) for the touch data to be exposed to JS at all.
Linux is not affected (backend never calls ProcessTouchData).

No in-the-wild crashes

Socorro shows zero crashes for ProcessTouchData, Dualshock4Remapper, GamepadRemapping, or WindowsGamepad — legitimate DualShock 4 controllers always send 64-byte reports, so this is not being hit by real devices.

Fix

The fix adds a length parameter to the ProcessTouchData virtual interface and validates aInputLen >= 43 before accessing any offsets. Windows passes dwSizeHid, macOS passes report_len.

Given the physical access requirement, the lossy data path, and the disabled-by-default multitouch pref gating JS exposure, I'd suggest sec-low rather than sec-moderate.

Note: bug 2025404 is a duplicate of this bug (same issue found independently by automated tooling).

Severity: -- → S3
Flags: needinfo?(cmartin)
Priority: -- → P2
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 151 Branch
Attached file (secure) —
Attachment #9562958 - Flags: approval-mozilla-beta?

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: A malicious USB HID could cause a heap buffer overflow.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing: none
  • Risk associated with taking this patch: low
  • Explanation of risk level: The patch just adds a bounds check where it should be.
  • String changes made/needed?: none
  • Is Android affected?: yes

firefox-esr140 Uplift Approval Request

  • User impact if declined/Reason for urgency: A malicious USB HID could cause a heap buffer overflow.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing: none
  • Risk associated with taking this patch: low
  • Explanation of risk level: The patch just adds a bounds check where it should be.
  • String changes made/needed?: none
  • Is Android affected?: yes
Attachment #9562959 - Flags: approval-mozilla-esr140?
Attached file (secure) —
Attachment #9562958 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9562959 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
QA Whiteboard: [sec] [uplift] [qa-triage-done-c151/b150]
Whiteboard: [adv-main150+]
Whiteboard: [adv-main150+] → [adv-main150+][adv-esr140.10+]
Alias: CVE-2026-6764
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: