[PATCH] HID: mcp2221: validate raw report length

Pengpeng Hou <[email protected]>
Newsgroups org.kernel.vger.linux-i2c,org.kernel.vger.linux-input,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
HID calls a driver raw_event() callback before it performs the generic
report-length validation. mcp2221_raw_event() subsequently reads fixed
response fields up to byte 55 and can copy a response payload through byte
63.

A short input report can therefore be interpreted using bytes beyond the
current report length before the HID core rejects it. Validate the
descriptor-derived report length at the beginning of the driver callback.

Complete the pending command with -EINVAL for a truncated report so that a
malformed response does not turn into an unrelated timeout.

Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge")
Signed-off-by: Pengpeng Hou <[email protected]>
---
 drivers/hid/hid-mcp2221.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index e4ddd8e9293b..67afef1a275f 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -861,6 +861,17 @@ static int mcp2221_raw_event(struct hid_device *hdev,
 	u8 *buf;
 	struct mcp2221 *mcp = hid_get_drvdata(hdev);
 
+	/*
+	 * HID invokes .raw_event() before its generic report-length check.
+	 * The response handlers below read fixed offsets from @data, so reject
+	 * a truncated current report before interpreting any of its fields.
+	 */
+	if (size < hid_report_len(report)) {
+		mcp->status = -EINVAL;
+		complete(&mcp->wait_in_report);
+		return 1;
+	}
+
 	switch (data[0]) {
 
 	case MCP2221_I2C_WR_DATA:
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.