The interrupt source count in a PDT entry is a 3-bit field, but the RMI4 specification only uses values 0-6 as a count; 7 is reserved to mean "more than 6 interrupt sources", which the driver does not support. The driver takes the value as is, and a function claiming 7 sources makes rmi_create_function_irq() and rmi_unregister_function() access fn->irq[6], one past the end of the array, clobbering fn->irq_pos: UBSAN: array-index-out-of-bounds in drivers/input/rmi4/rmi_bus.c:183:10 index 6 is out of range for type 'int [6]' Reject such entries in rmi_scan_pdt_page(). The check has to come after the RMI4_END_OF_PDT() test: an unpopulated entry reads as 0xff, which also decodes to 7 interrupt sources, and must still terminate the scan. Fixes: 24d28e4f1271 ("Input: synaptics-rmi4 - convert irq distribution to irq_domain") Cc: stable@vger.kernel.org Suggested-by: Dmitry Torokhov Assisted-by: LLM Signed-off-by: Wei Jie Law <98lawweijie@gmail.com> --- drivers/input/rmi4/rmi_driver.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 5d49a9021c7d..443ba4106352 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -526,6 +526,19 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev, if (RMI4_END_OF_PDT(pdt_entry.function_number)) break; + /* + * A count of 7 means "more than 6 interrupt sources", which is + * not supported. Checked after RMI4_END_OF_PDT() because an + * unpopulated (0xff) entry also decodes to 7. + */ + if (pdt_entry.interrupt_source_count > RMI_FN_MAX_IRQS) { + dev_err(&rmi_dev->dev, + "F%02X: invalid interrupt source count %u\n", + pdt_entry.function_number, + pdt_entry.interrupt_source_count); + return -EINVAL; + } + retval = callback(rmi_dev, ctx, &pdt_entry); if (retval != RMI_SCAN_CONTINUE) return retval; -- 2.43.0