Out-of-bounds read in LinuxGamepadService::OnGamepadData from KEY_MAX vs KEY_CNT array sizing
Categories
(Core :: DOM: Device Interfaces, defect)
Tracking
()
People
(Reporter: Sylvestre, Assigned: Sylvestre)
References
(Blocks 1 open bug, Regression)
Details
(Keywords: regression)
Attachments
(3 external files)
Found via Coverity (CID 1585304, "Untrusted array index read").
In dom/gamepad/linux/LinuxGamepad.cpp, struct Gamepad declares uint8_t key_map[KEY_MAX] and uint8_t abs_map[ABS_MAX] (767 and 63 elements). But the kernel evdev layer admits EV_KEY codes up to KEY_MAX inclusive (is_event_supported uses code <= KEY_MAX), so in OnGamepadData an event with event.code == KEY_MAX (767) reads key_map[767] -- one element past the end of the array. The population loop (for (uint16_t key = 0; key < KEY_MAX; key++)) has the same exclusive-bound issue. Note that keyBits/absBits in AddDevice are already correctly sized with KEY_CNT/ABS_CNT, so a device bit can be set at an index key_map cannot store.
Additionally, the EV_KEY path indexes key_map with the untrusted device-supplied event.code without any bounds check, unlike the EV_ABS path which is guarded by abs_info.count(event.code).
Impact is low: the one-past-the-end byte lands on the adjacent in-struct member abs_map[0] (valid allocated memory), so there is no crash or information leak -- worst case a spurious button index. It is not web-reachable: web content cannot control event.code; triggering code == 767 requires a local uinput virtual joystick device (needs /dev/uinput privilege).
Fix: size the arrays with KEY_CNT/ABS_CNT, match the population-loop bounds, and add an explicit event.code >= KEY_CNT guard in the EV_KEY branch
| Assignee | ||
Comment 1•3 months ago
|
||
key_map/abs_map were sized [KEY_MAX]/[ABS_MAX], but evdev admits EV_KEY codes up to KEY_MAX inclusive, so event.code == KEY_MAX read one past the end. Size the arrays and population loops with KEY_CNT/ABS_CNT (matching keyBits/absBits), and bound the untrusted event.code before indexing key_map.
Updated•3 months ago
|
Comment 3•3 months ago
|
||
| bugherder | ||
Updated•3 months ago
|
Comment 5•3 months ago
|
||
Set release status flags based on info from the regressing bug 1680982
Comment 6•3 months ago
|
||
The patch landed in nightly and beta is affected.
:Sylvestre, is this bug important enough to require an uplift?
- If yes, please nominate the patch for beta approval.
- See https://wiki.mozilla.org/Release_Management/Requesting_an_Uplift for documentation on how to request an uplift.
- If no, please set
status-firefox153towontfix.
For more information, please visit BugBot documentation.
Updated•3 months ago
|
Comment 7•3 months ago
|
||
Set release status flags based on info from the regressing bug 1680982
Updated•3 months ago
|
Updated•2 months ago
|
Comment 8•2 months ago
|
||
firefox-esr140 Uplift Approval Request
- User impact if declined/Reason for urgency: potential crashes
- Code covered by automated testing?: unknown
- Fix verified in Nightly?: yes
- Needs manual QE testing?: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: just a check
- String changes made/needed?: no
- Is Android affected?: no
| Assignee | ||
Comment 9•2 months ago
|
||
key_map/abs_map were sized [KEY_MAX]/[ABS_MAX], but evdev admits EV_KEY codes up to KEY_MAX inclusive, so event.code == KEY_MAX read one past the end. Size the arrays and population loops with KEY_CNT/ABS_CNT (matching keyBits/absBits), and bound the untrusted event.code before indexing key_map.
Original Revision: https://phabricator.services.mozilla.com/D310336
Comment 10•2 months ago
|
||
firefox-esr153 Uplift Approval Request
- User impact if declined/Reason for urgency: potential crashes
- Code covered by automated testing?: unknown
- Fix verified in Nightly?: yes
- Needs manual QE testing?: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: just a check
- String changes made/needed?: no
- Is Android affected?: no
| Assignee | ||
Comment 11•2 months ago
|
||
key_map/abs_map were sized [KEY_MAX]/[ABS_MAX], but evdev admits EV_KEY codes up to KEY_MAX inclusive, so event.code == KEY_MAX read one past the end. Size the arrays and population loops with KEY_CNT/ABS_CNT (matching keyBits/absBits), and bound the untrusted event.code before indexing key_map.
Original Revision: https://phabricator.services.mozilla.com/D310336
| Assignee | ||
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Comment 12•2 months ago
|
||
| uplift | ||
Updated•2 months ago
|
Comment 13•2 months ago
|
||
| uplift | ||
Description
•