Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 0/2] (no cover subject)
@ 2026-06-14  5:36 Bryam Vargas via B4 Relay
  2026-06-14  5:36 ` [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count Bryam Vargas via B4 Relay
  2026-06-14  5:36 ` [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count Bryam Vargas via B4 Relay
  0 siblings, 2 replies; 5+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-06-14  5:36 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, Hans de Goede, Vincent Huang, linux-input,
	Andrew Duggan

From be2c4843f6145374f28edd25cef43c9373542874 Mon Sep 17 00:00:00 2001
Message-ID: <cover.1781415009.git.hexlabsecurity@proton.me>
From: Bryam Vargas <hexlabsecurity@proton.me>
Date: Sun, 14 Jun 2026 00:30:09 -0500
Subject: [PATCH 0/2] Input: synaptics-rmi4 - fix out-of-bounds keymap access on large GPIO counts

The RMI4 F3A and F30 function handlers size their GPIO/LED key map to
min(device_gpio_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
then consume that map with the full, unclamped device-reported count in
two places: the attention-interrupt report loop, and input->keycodemax
(while input->keycode points at the small allocation).

A device that reports a GPIO/LED count greater than 6 therefore yields a
key map of at most 12 bytes that is indexed up to count-1:

  - rmi_f3a_attention() / rmi_f30_attention() read gpio[led]_key_map[i]
    out of bounds on every attention interrupt (device-triggered), and

  - the input core's default keymap ioctls bound the index only against
    keycodemax, so EVIOCGKEYCODE reads adjacent slab memory back to user
    space and EVIOCSKEYCODE writes a caller-controlled u16 past the
    allocation -- a controlled out-of-bounds heap write reachable by any
    process that can open the evdev node.

Both handlers have the same shape; F3A was copied from F30. Patch 1 fixes
F3A, patch 2 fixes F30. The one-line fix in each sizes the key map to the
full device count; the mapping loop is unchanged (it still populates only
the first min(count, 6) entries, the rest stay KEY_RESERVED and are
skipped on report), and keycodemax now matches the allocation, closing
the interrupt and both ioctl paths.

Reproduced with KASAN on a faithful in-kernel model of each handler
(kmalloc-16 bucket, 12-byte request, reported count = 127):

  # without the patch -- attention read path
  BUG: KASAN: slab-out-of-bounds in rmi_f3a_attention
  Read of size 2 ... 0 bytes to the right of allocated 12-byte region
    ... cache kmalloc-16

  # without the patch -- EVIOCSKEYCODE write path
  BUG: KASAN: slab-out-of-bounds ...
  Write of size 2 ... 0 bytes to the right of allocated 12-byte region

  # with the patch (key map sized to the full count): clean
  # benign device (reported count <= 6): clean

The full read and write splats and a 32/64-bit ASan model of the same
geometry are available on request.

Bryam Vargas (2):
  Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count
  Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count

 drivers/input/rmi4/rmi_f30.c | 2 +-
 drivers/input/rmi4/rmi_f3a.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

base-commit: 8e65320d91cdc3b241d4b94855c88459b91abf66
---
Bryam Vargas (2):
      Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count
      Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count

 drivers/input/rmi4/rmi_f30.c | 2 +-
 drivers/input/rmi4/rmi_f3a.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
---
base-commit: 8e65320d91cdc3b241d4b94855c88459b91abf66
change-id: 20260614-b4-disp-818d6bda-8df90972ace6

Best regards,
-- 
Bryam Vargas <hexlabsecurity@proton.me>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count
  2026-06-14  5:36 [PATCH 0/2] (no cover subject) Bryam Vargas via B4 Relay
@ 2026-06-14  5:36 ` Bryam Vargas via B4 Relay
  2026-06-14  5:51   ` sashiko-bot
  2026-06-14  5:36 ` [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count Bryam Vargas via B4 Relay
  1 sibling, 1 reply; 5+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-06-14  5:36 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, Hans de Goede, Vincent Huang, linux-input,
	Andrew Duggan

From: Bryam Vargas <hexlabsecurity@proton.me>

rmi_f3a_initialize() takes the GPIO count from the device query register
(f3a->gpio_count = buf & RMI_F3A_GPIO_COUNT, range 0..127).
rmi_f3a_map_gpios() then allocates gpio_key_map with
min(gpio_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f3a_attention() iterates the full gpio_count and dereferences
gpio_key_map[i], and input->keycodemax is set to the full gpio_count
while input->keycode points at the 6-entry allocation.

A device that reports gpio_count > 6 therefore causes an out-of-bounds
read of gpio_key_map[] on every attention interrupt, and out-of-bounds
accesses through the input core's default keymap ioctls: EVIOCGKEYCODE
reads past the buffer (leaking adjacent slab memory to user space) and
EVIOCSKEYCODE writes a caller-controlled value past it, for any process
able to open the evdev node, since input_default_getkeycode() and
input_default_setkeycode() only bound the index against keycodemax.

Size the keymap for the full gpio_count. The mapping loop is unchanged:
it still assigns only the first min(gpio_count, TRACKSTICK_RANGE_END)
entries; the remaining slots stay KEY_RESERVED (devm_kcalloc zero-fills)
and are skipped when reporting.

Fixes: 9e4c596bfd00 ("Input: synaptics-rmi4 - add support for F3A")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
 drivers/input/rmi4/rmi_f3a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/rmi4/rmi_f3a.c b/drivers/input/rmi4/rmi_f3a.c
index 0e8baed84dbb..a0777644eef0 100644
--- a/drivers/input/rmi4/rmi_f3a.c
+++ b/drivers/input/rmi4/rmi_f3a.c
@@ -132,7 +132,7 @@ static int rmi_f3a_map_gpios(struct rmi_function *fn, struct f3a_data *f3a,
 	int button_count = min_t(u8, f3a->gpio_count, TRACKSTICK_RANGE_END);
 
 	f3a->gpio_key_map = devm_kcalloc(&fn->dev,
-						button_count,
+						f3a->gpio_count,
 						sizeof(f3a->gpio_key_map[0]),
 						GFP_KERNEL);
 	if (!f3a->gpio_key_map) {

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count
  2026-06-14  5:36 [PATCH 0/2] (no cover subject) Bryam Vargas via B4 Relay
  2026-06-14  5:36 ` [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count Bryam Vargas via B4 Relay
@ 2026-06-14  5:36 ` Bryam Vargas via B4 Relay
  2026-06-14  5:50   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-06-14  5:36 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, Hans de Goede, Vincent Huang, linux-input,
	Andrew Duggan

From: Bryam Vargas <hexlabsecurity@proton.me>

rmi_f30_map_gpios() allocates gpioled_key_map with
min(gpioled_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f30_attention() iterates the full f30->gpioled_count (device query
register, range 0..31) and dereferences gpioled_key_map[i], and
input->keycodemax is set to the full gpioled_count while input->keycode
points at the 6-entry allocation.

A device that reports gpioled_count > 6 with GPIO support enabled
therefore causes an out-of-bounds read on the attention interrupt and
out-of-bounds read/write through the EVIOCGKEYCODE/EVIOCSKEYCODE ioctls,
which bound the index only against keycodemax. This is the same defect
as the F3A handler, which was copied from F30.

Size the keymap for the full gpioled_count; the mapping loop still
assigns only the first min(gpioled_count, TRACKSTICK_RANGE_END) entries.

Fixes: 3e64fcbdbd10 ("Input: synaptics-rmi4 - limit the range of what GPIOs are buttons")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
 drivers/input/rmi4/rmi_f30.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
index 35045f161dc2..b2155c8e20e7 100644
--- a/drivers/input/rmi4/rmi_f30.c
+++ b/drivers/input/rmi4/rmi_f30.c
@@ -233,7 +233,7 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
 	int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END);
 
 	f30->gpioled_key_map = devm_kcalloc(&fn->dev,
-					    button_count,
+					    f30->gpioled_count,
 					    sizeof(f30->gpioled_key_map[0]),
 					    GFP_KERNEL);
 	if (!f30->gpioled_key_map) {

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count
  2026-06-14  5:36 ` [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count Bryam Vargas via B4 Relay
@ 2026-06-14  5:50   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-06-14  5:50 UTC (permalink / raw)
  To: Bryam Vargas via B4 Relay; +Cc: linux-input, dmitry.torokhov

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Unbinding the `rmi4_f30` driver leaves a dangling pointer in the shared input device's `keycode` field, leading to a Use-After-Free.
--

commit 251790cc33b0da19e8d0320efecb822396ad7b5f
Author: Bryam Vargas <hexlabsecurity@proton.me>

Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count

This commit fixes an out-of-bounds read and write issue in the F30
keymap handler. It allocates the keymap based on the full reported
GPIO/LED count rather than capping the allocation at 6 entries.

> diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> --- a/drivers/input/rmi4/rmi_f30.c
> +++ b/drivers/input/rmi4/rmi_f30.c
> @@ -233,7 +233,7 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
>  	int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END);
>  
>  	f30->gpioled_key_map = devm_kcalloc(&fn->dev,
> -					    button_count,
> +					    f30->gpioled_count,
>  					    sizeof(f30->gpioled_key_map[0]),
>  					    GFP_KERNEL);

[Severity: High]
This is a pre-existing issue, but since we are modifying this allocation,
can this lead to a use-after-free when the driver is unbound?

The memory for f30->gpioled_key_map is managed by the function subdevice
using fn->dev. Later in rmi_f30_map_gpios(), this pointer is assigned to the
shared input device's keycode field:

input->keycode = f30->gpioled_key_map;

Since the shared input device is attached to the parent RMI device, it can
outlive the function subdevice. If userspace unbinds the rmi4_f30 driver
via sysfs (because the driver lacks a remove callback and does not set
suppress_bind_attrs), devres will free f30->gpioled_key_map while
the input device remains registered.

Would a subsequent ioctl like EVIOCGKEYCODE or EVIOCSKEYCODE access this
freed input->keycode memory?

Does this also cause a race condition during device unplug, since the
function devices are unbound before the input device is unregistered?

>  	if (!f30->gpioled_key_map) {

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260614-b4-disp-818d6bda-v1-0-cf39a3615085@proton.me?part=2

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count
  2026-06-14  5:36 ` [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count Bryam Vargas via B4 Relay
@ 2026-06-14  5:51   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-06-14  5:51 UTC (permalink / raw)
  To: Bryam Vargas via B4 Relay; +Cc: dmitry.torokhov, linux-input

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [High] Out-of-bounds shift and logic error in `rmi_f3a_report_button` when `button >= 8`.
- [High] Unbinding the `rmi4_f3a` driver leaves a dangling `input->keycode` pointer, leading to a Use-After-Free.
- [High] Failing to insert into the attention FIFO leaks the dynamically allocated duplicate buffer.
- [Medium] Multiple RMI4 functions concurrently overwrite the shared `input->keycode` map, making all but the last probed map inaccessible to userspace.
--

commit 1556a27ea7ad4e1c54736060ac2c334003a11681
Author: Bryam Vargas <hexlabsecurity@proton.me>

Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count

This commit addresses an out-of-bounds access in the F3A keymap. It sizes the
gpio_key_map buffer to the full gpio_count rather than capping it at 6,
preventing reads or writes past the allocated array during attention
interrupts or keymap ioctls.

> diff --git a/drivers/input/rmi4/rmi_f3a.c b/drivers/input/rmi4/rmi_f3a.c
> index 0e8baed84dbb5..a0777644eef07 100644
> --- a/drivers/input/rmi4/rmi_f3a.c
> +++ b/drivers/input/rmi4/rmi_f3a.c
> @@ -132,7 +132,7 @@ static int rmi_f3a_map_gpios(struct rmi_function *fn, struct f3a_data *f3a,
>  	int button_count = min_t(u8, f3a->gpio_count, TRACKSTICK_RANGE_END);
>  
>  	f3a->gpio_key_map = devm_kcalloc(&fn->dev,
> -						button_count,
> +						f3a->gpio_count,
>  						sizeof(f3a->gpio_key_map[0]),
>  						GFP_KERNEL);

[Severity: High]
This isn't a bug introduced by this patch, but I have a question about the
lifecycle of the keymap allocated here.

Since input->keycode is set to f3a->gpio_key_map later in this function, if
the rmi4_f3a function driver is unbound via sysfs, devres will free this
memory. Because rmi_f3a_handler lacks a .remove callback and does not set
.suppress_bind_attrs = true, does this leave input->keycode pointing to freed
memory? Could subsequent EVIOCGKEYCODE or EVIOCSKEYCODE ioctls on the shared
input_dev dereference this freed pointer?

[Severity: Medium]
This is a pre-existing issue, but I also noticed how this keymap interacts
with the shared input device.

Both F3A and F30 assign their own private arrays to the shared input->keycode:

drivers/input/rmi4/rmi_f3a.c:rmi_f3a_map_gpios() {
    ...
    input->keycode = f3a->gpio_key_map;
    ...
}

drivers/input/rmi4/rmi_f30.c:rmi_f30_map_gpios() {
    ...
    input->keycode = f30->gpioled_key_map;
    ...
}

Since multiple RMI4 functions concurrently overwrite the shared
input->keycode, does this make all but the last probed map inaccessible to
userspace? Would earlier functions then report events using their
unmodifiable, private arrays?

>  	if (!f3a->gpio_key_map) {

[ ... ]

[Severity: High]
This is a pre-existing issue, but looking at rmi_f3a_report_button() in
drivers/input/rmi4/rmi_f3a.c:

drivers/input/rmi4/rmi_f3a.c:rmi_f3a_report_button() {
    ...
    bool key_down = !(f3a->data_regs[0] & BIT(button));
    ...
}

Since f3a->data_regs is a u8 array, could this incorrectly report the key as
constantly pressed if button >= 8? If button >= 32, could this result in an
out-of-bounds shift? Since userspace can map a high button index via
EVIOCSKEYCODE and trigger an interrupt, could this be triggered intentionally?

[Severity: High]
This is a pre-existing issue, but looking at rmi_set_attn_data() in
drivers/input/rmi4/rmi_driver.c:

drivers/input/rmi4/rmi_driver.c:rmi_set_attn_data() {
    ...
    fifo_data = kmemdup(data, size, GFP_ATOMIC);
    ...
    attn_data.data = fifo_data;
    ...
    kfifo_put(&drvdata->attn_fifo, attn_data);
    ...
}

If kfifo_put() fails because the FIFO is full, does this silently leak the
dynamically allocated fifo_data buffer? Could a flood of interrupts lead to
memory exhaustion?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260614-b4-disp-818d6bda-v1-0-cf39a3615085@proton.me?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-14  5:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-14  5:36 [PATCH 0/2] (no cover subject) Bryam Vargas via B4 Relay
2026-06-14  5:36 ` [PATCH 1/2] Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count Bryam Vargas via B4 Relay
2026-06-14  5:51   ` sashiko-bot
2026-06-14  5:36 ` [PATCH 2/2] Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count Bryam Vargas via B4 Relay
2026-06-14  5:50   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox