[PATCH] Input: cyapa - cap the PIP report length before the I2C read
From: Linkai Gong
Date: Thu Sep 03 2026 - 03:59:58 EST
The 16-bit PIP length is used as the i2c_master_recv() size
into a stack struct of 10 contacts. The 127-byte check runs
after that read. Also clamp the 5-bit contact count.
Fixes: 6972a859601a ("Input: cyapa - add gen5 trackpad device basic functions support")
Signed-off-by: Linkai Gong <gonglinkai@xxxxxxxxxx>
---
drivers/input/mouse/cyapa_gen5.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
index 59f6e97d5482..0c8bc37ab3fd 100644
--- a/drivers/input/mouse/cyapa_gen5.c
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -2750,12 +2750,14 @@ static void cyapa_pip_report_touches(struct cyapa *cyapa,
struct input_dev *input = cyapa->input;
unsigned int touch_num;
int i;
touch_num = report_data->report_head[PIP_NUMBER_OF_TOUCH_OFFSET] &
PIP_NUMBER_OF_TOUCH_MASK;
+ if (touch_num > ARRAY_SIZE(report_data->touch_records))
+ touch_num = ARRAY_SIZE(report_data->touch_records);
for (i = 0; i < touch_num; i++)
cyapa_pip_report_slot_data(cyapa,
&report_data->touch_records[i]);
input_mt_sync_frame(input);
@@ -2781,13 +2783,14 @@ int cyapa_pip_irq_handler(struct cyapa *cyapa)
dev_err(dev, "failed to read length bytes, (%d)\n", ret);
return -EINVAL;
}
report_len = get_unaligned_le16(
&report_data.report_head[PIP_RESP_LENGTH_OFFSET]);
- if (report_len < PIP_RESP_LENGTH_SIZE) {
+ if (report_len < PIP_RESP_LENGTH_SIZE ||
+ report_len > sizeof(report_data)) {
/* Invalid length or internal reset happened. */
dev_err(dev, "invalid report_len=%d. bytes: %02x %02x\n",
report_len, report_data.report_head[0],
report_data.report_head[1]);
return -EINVAL;
}
--
2.25.1