summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Lecomte <contact@arnaud-lcm.com>2025-07-26 23:09:31 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-12 13:01:03 +0200
commit51627f45b304f2abfd5397ed39b639e70acf09b3 (patch)
tree2e56d73ddcd894014e8f263eee51bcb71d23c814
parent4a6d6310349a525278afccdbce6d514cd16a3bac (diff)
downloadlinux-51627f45b304f2abfd5397ed39b639e70acf09b3.tar.gz
linux-51627f45b304f2abfd5397ed39b639e70acf09b3.tar.bz2
linux-51627f45b304f2abfd5397ed39b639e70acf09b3.zip
hid: fix I2C read buffer overflow in raw_event() for mcp2221
commit b56cc41a3ae7323aa3c6165f93c32e020538b6d2 upstream. As reported by syzbot, mcp2221_raw_event lacked validation of incoming I2C read data sizes, risking buffer overflows in mcp->rxbuf during multi-part transfers. As highlighted in the DS20005565B spec, p44, we have: "The number of read-back data bytes to follow in this packet: from 0 to a maximum of 60 bytes of read-back bytes." This patch enforces we don't exceed this limit. Reported-by: syzbot+52c1a7d3e5b361ccd346@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=52c1a7d3e5b361ccd346 Tested-by: syzbot+52c1a7d3e5b361ccd346@syzkaller.appspotmail.com Signed-off-by: Arnaud Lecomte <contact@arnaud-lcm.com> Link: https://patch.msgid.link/20250726220931.7126-1-contact@arnaud-lcm.com Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Romain Sioen <romain.sioen@microchip.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/hid/hid-mcp2221.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index 6c0ac14f11a6..2cfc8e1a2912 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -816,6 +816,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
}
if (data[2] == MCP2221_I2C_READ_COMPL ||
data[2] == MCP2221_I2C_READ_PARTIAL) {
+ if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) {
+ mcp->status = -EINVAL;
+ break;
+ }
buf = mcp->rxbuf;
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];