Input updates for v7.2-rc0-2

- Updates to Synaptics RMI4 driver to fix potential OOB accesses in
   F30 and F3A keymap handling
 
 - A workaround in Synaptics RMI4 to tolerate buggy firmware on some
   touchpads (e.g. ThinkPad T14 Gen 1) that report incomplete register
   descriptor structures, preventing probe failures
 
 - A revert of an incorrect register descriptor address calculation in
   Synaptics RMI4 driver
 
 - A fix for a regression in HP GSC PS/2 (gscps2) driver where the
   receive buffer write index was not advanced, leaving keyboard and
   mouse unusable.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQST2eWILY88ieB2DOtAj56VGEWXnAUCakCsxwAKCRBAj56VGEWX
 nCICAQDSgfrAi+4SqTb92EjtdQO+ypluS42mKO75LTitJcS8dAEA1iKmdss8mGww
 c4ai4W+UFxori7IqgkoQ7LfaPTOWlA0=
 =QP4c
 -----END PGP SIGNATURE-----

Merge tag 'input-for-v7.2-rc0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull more input updates from Dmitry Torokhov:

 - Updates to Synaptics RMI4 driver to fix potential OOB accesses in F30
   and F3A keymap handling

 - A workaround in Synaptics RMI4 to tolerate buggy firmware on some
   touchpads (e.g. ThinkPad T14 Gen 1) that report incomplete register
   descriptor structures, preventing probe failures

 - A revert of an incorrect register descriptor address calculation in
   Synaptics RMI4 driver

 - A fix for a regression in HP GSC PS/2 (gscps2) driver where the
   receive buffer write index was not advanced, leaving keyboard and
   mouse unusable.

* tag 'input-for-v7.2-rc0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: gscps2 - advance receive buffer write index
  Input: rmi4 - tolerate short register descriptor structure
  Revert "Input: rmi4 - fix register descriptor address calculation"
  Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count
  Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count
This commit is contained in:
Linus Torvalds 2026-06-28 04:40:05 -07:00
commit 8b69c04758
4 changed files with 29 additions and 15 deletions

View File

@ -616,8 +616,8 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
unsigned int presence_offset;
unsigned int map_offset;
unsigned int offset;
unsigned int num_registers;
unsigned int reg;
int i;
int b;
int ret;
@ -643,7 +643,7 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
ret = rmi_read_block(d, addr, buf, size_presence_reg);
if (ret)
return ret;
addr += size_presence_reg;
++addr;
if (buf[0] == 0) {
if (size_presence_reg < 3)
@ -657,7 +657,7 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
memset(presence_map, 0, sizeof(presence_map));
map_offset = 0;
for (i = presence_offset; i < size_presence_reg; i++) {
for (int i = presence_offset; i < size_presence_reg; i++) {
for (b = 0; b < 8; b++) {
if (buf[i] & BIT(b)) {
if (map_offset >= RMI_REG_DESC_PRESENCE_BITS)
@ -697,28 +697,41 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
if (ret)
return ret;
reg = find_first_bit(presence_map, RMI_REG_DESC_PRESENCE_BITS);
offset = 0;
for (i = 0; i < rdesc->num_registers; i++) {
struct rmi_register_desc_item *item = &rdesc->registers[i];
num_registers = 0;
for_each_set_bit(reg, presence_map, RMI_REG_DESC_PRESENCE_BITS) {
struct rmi_register_desc_item *item = &rdesc->registers[num_registers];
int item_size;
if (offset >= rdesc->struct_size)
break;
item_size = rmi_parse_register_desc_item(item,
&struct_buf[offset],
rdesc->struct_size - offset);
if (item_size < 0)
return item_size;
if (item_size < 0) {
dev_warn(&d->dev,
"%s: Failed to parse register %d descriptor, ignoring it\n",
__func__, reg);
break;
}
item->reg = reg;
offset += item_size;
rmi_dbg(RMI_DEBUG_CORE, &d->dev,
"%s: reg: %d reg size: %u subpackets: %d\n", __func__,
item->reg, item->reg_size, item->num_subpackets);
if (item->reg_size == 0) {
dev_warn(&d->dev,
"%s: Register %d has 0 size, ignoring it\n",
__func__, item->reg);
} else {
rmi_dbg(RMI_DEBUG_CORE, &d->dev,
"%s: reg: %d reg size: %u subpackets: %d\n", __func__,
item->reg, item->reg_size, item->num_subpackets);
reg = find_next_bit(presence_map,
RMI_REG_DESC_PRESENCE_BITS, reg + 1);
num_registers++;
}
}
rdesc->num_registers = num_registers;
return 0;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -219,6 +219,7 @@ static void gscps2_read_data(struct gscps2port *ps2port)
ps2port->buffer[ps2port->append].str = status;
ps2port->buffer[ps2port->append].data =
gscps2_readb_input(ps2port->addr);
ps2port->append = (ps2port->append + 1) & BUFFER_SIZE;
} while (true);
}