Commit cba3a9c
committed
input: bound input_remap_ids[] against analog_value[][8] OOB write
input_driver.c's poll-time remap loop indexed
mapper->analog_value[i][n] using values from
settings->uints.input_remap_ids[i][k] without proper bounds in
two places:
1. Button -> analog branch (line ~7392):
handle->analog_value[i][remap_button - RARCH_FIRST_CUSTOM_BIND] = ...
No bound on remap_button at all. Reachable values:
[RARCH_FIRST_CUSTOM_BIND, RARCH_UNMAPPED) i.e. [16, 1024),
producing remap_axis_bind in [0, 1008). Indexing past the
8-element row writes int16_t values up to ~2014 bytes past
the end of analog_value, into adjacent input_mapper_t
fields (keys[], key_button[], buttons[]) and beyond into
adjacent input_driver_state_t fields.
2. Analog -> analog branch (line ~7427):
if (remap_axis_bind < sizeof(handle->analog_value[i]))
handle->analog_value[i][remap_axis_bind] = ...
The sizeof() returns 16 (the byte size of the int16_t[8]
row), not the element count. Indices 8..15 passed the
check and OOB-wrote into the next user's analog_value row,
or past the array entirely for the last user.
Both sites read remap_button / remap_axis from
settings->uints.input_remap_ids[i][k], which is loaded from
.rmp files via input_remapping_load_file in configuration.c.
Pre-this-patch the loader fed config_get_int's result directly
into storage with no range check, so a malformed .rmp could
plant any int there. An attacker who can deliver a .rmp
alongside a ROM (a common distribution channel for
"controller config bundles") gets a 60Hz attacker-controlled
out-of-bounds write into adjacent input state -- including
the keys[] keyboard bitmask for the last user, which controls
which RetroArch hotkeys appear pressed.
Two-pronged fix:
- Load-time validation in input_remapping_load_file:
reject _remap values outside [0, RARCH_ANALOG_BIND_LIST_END)
(clamping to RARCH_UNMAPPED) before storing into
settings->uints.input_remap_ids[i][j]. Applied to both the
button-branch (j < RARCH_FIRST_CUSTOM_BIND) and the
analog-branch (j >= RARCH_FIRST_CUSTOM_BIND) of the
loader.
- Use-site bounds in input_driver.c: add an
ARRAY_SIZE-based bound to the previously-unguarded
button -> analog branch, and replace the broken sizeof()
bound with ARRAY_SIZE() in the analog -> analog branch.
Defence in depth: even if the load-time validator misses
a path (or a future caller writes to input_remap_ids[]
bypassing the loader), the use sites are now safe.
Adds samples/tasks/input_remap/input_remap_bounds_test as a
regression test, registered in
.github/workflows/Linux-samples-tasks.yml as an ASan-enabled
step. Seven cases covering the load-time clamp's accept and
reject paths, in-range writes going to the correct slot,
out-of-range writes being skipped without OOB, and the
specific historical sizeof-vs-ARRAY_SIZE bug shape.
Test follows the existing samples/tasks pattern (verbatim copy
of the post-fix predicates with a maintenance-contract comment;
ASan as the discriminator). Verified to fire under ASan when
the bound check is removed: heap-buffer-overflow WRITE of size
2 at offset 16 of a 16-byte allocation, in
do_button_to_analog_write. With the bound the test passes
clean.1 parent 1fe435a commit cba3a9c
5 files changed
Lines changed: 439 additions & 4 deletions
File tree
- .github/workflows
- input
- samples/tasks/input_remap
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6984 | 6984 | | |
6985 | 6985 | | |
6986 | 6986 | | |
| 6987 | + | |
| 6988 | + | |
| 6989 | + | |
| 6990 | + | |
| 6991 | + | |
| 6992 | + | |
| 6993 | + | |
| 6994 | + | |
| 6995 | + | |
| 6996 | + | |
| 6997 | + | |
| 6998 | + | |
| 6999 | + | |
| 7000 | + | |
| 7001 | + | |
6987 | 7002 | | |
6988 | 7003 | | |
6989 | 7004 | | |
| |||
7012 | 7027 | | |
7013 | 7028 | | |
7014 | 7029 | | |
| 7030 | + | |
| 7031 | + | |
| 7032 | + | |
| 7033 | + | |
| 7034 | + | |
| 7035 | + | |
7015 | 7036 | | |
7016 | 7037 | | |
7017 | 7038 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7384 | 7384 | | |
7385 | 7385 | | |
7386 | 7386 | | |
7387 | | - | |
| 7387 | + | |
| 7388 | + | |
| 7389 | + | |
| 7390 | + | |
| 7391 | + | |
| 7392 | + | |
| 7393 | + | |
| 7394 | + | |
| 7395 | + | |
| 7396 | + | |
| 7397 | + | |
| 7398 | + | |
| 7399 | + | |
| 7400 | + | |
| 7401 | + | |
7388 | 7402 | | |
7389 | 7403 | | |
7390 | 7404 | | |
7391 | 7405 | | |
7392 | | - | |
7393 | | - | |
| 7406 | + | |
7394 | 7407 | | |
7395 | 7408 | | |
7396 | 7409 | | |
| |||
7424 | 7437 | | |
7425 | 7438 | | |
7426 | 7439 | | |
7427 | | - | |
| 7440 | + | |
| 7441 | + | |
| 7442 | + | |
| 7443 | + | |
| 7444 | + | |
7428 | 7445 | | |
7429 | 7446 | | |
7430 | 7447 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
0 commit comments