public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Input: synaptics-rmi4 - validate register descriptor structure against its declared size
@ 2026-04-20 18:59 Greg Kroah-Hartman
  2026-04-20 18:59 ` [PATCH 2/2] Input: synaptics-rmi4 - use u32 for reg_size to avoid sign extension into item->reg_size Greg Kroah-Hartman
  0 siblings, 1 reply; 2+ messages in thread
From: Greg Kroah-Hartman @ 2026-04-20 18:59 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel, Greg Kroah-Hartman, Dmitry Torokhov, stable

rmi_read_register_desc() trusts three independent device-supplied
quantities to be correct:
  - struct_size, taken from the presence-register header (up to 65535
    via buf[1]|buf[2]<<8 when buf[0]==0),
  - num_registers, the popcount of the presence bitmap (up to 255),
  - the per-register entries inside struct_buf, each a variable-length
    {reg_size, subpacket-continuation-bytes...} record.

But nothing checks that num_registers entries actually fit in
struct_size bytes, and nothing bounds the subpacket continuation chain,
which can cause two different types of overruns if left unchecked.

Fix this all up by properly checking the values every time and aborting
if anything is out of range.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Fixes: 2b6a321da9a2 ("Input: synaptics-rmi4 - add support for Synaptics RMI4 devices")
Cc: stable <stable@kernel.org>
Assisted-by: gkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/rmi4/rmi_driver.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index ccd9338a44db..9143f11e42a3 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -643,16 +643,24 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
 	reg = find_first_bit(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS);
 	for (i = 0; i < rdesc->num_registers; i++) {
 		struct rmi_register_desc_item *item = &rdesc->registers[i];
-		int reg_size = struct_buf[offset];
+		int reg_size;
+
+		if (offset >= rdesc->struct_size)
+			goto malformed;
+		reg_size = struct_buf[offset];
 
 		++offset;
 		if (reg_size == 0) {
+			if (offset + 2 > rdesc->struct_size)
+				goto malformed;
 			reg_size = struct_buf[offset] |
 					(struct_buf[offset + 1] << 8);
 			offset += 2;
 		}
 
 		if (reg_size == 0) {
+			if (offset + 4 > rdesc->struct_size)
+				goto malformed;
 			reg_size = struct_buf[offset] |
 					(struct_buf[offset + 1] << 8) |
 					(struct_buf[offset + 2] << 16) |
@@ -666,6 +674,9 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
 		map_offset = 0;
 
 		do {
+			if (offset >= rdesc->struct_size ||
+			    map_offset >= RMI_REG_DESC_SUBPACKET_BITS)
+				goto malformed;
 			for (b = 0; b < 7; b++) {
 				if (struct_buf[offset] & (0x1 << b))
 					bitmap_set(item->subpacket_map,
@@ -688,6 +699,12 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
 free_struct_buff:
 	kfree(struct_buf);
 	return ret;
+
+malformed:
+	dev_err(&d->dev,
+		"register descriptor structure does not match its declared size\n");
+	ret = -EIO;
+	goto free_struct_buff;
 }
 
 const struct rmi_register_desc_item *rmi_get_register_desc_item(
-- 
2.53.0


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

end of thread, other threads:[~2026-04-20 18:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 18:59 [PATCH 1/2] Input: synaptics-rmi4 - validate register descriptor structure against its declared size Greg Kroah-Hartman
2026-04-20 18:59 ` [PATCH 2/2] Input: synaptics-rmi4 - use u32 for reg_size to avoid sign extension into item->reg_size Greg Kroah-Hartman

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