summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Zaidman <michael.zaidman@gmail.com>2026-08-26 13:48:07 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-02 14:28:34 +0200
commitf9fa2e2dc0269a54c186a9f6701e20c24b1d67b0 (patch)
treea3f4e247c8b43b1c16fd7e902d88e1c97eba7941
parent65d6c17a1e393b626c8872fae85c6d3dc2229949 (diff)
downloadlinux-f9fa2e2dc0269a54c186a9f6701e20c24b1d67b0.tar.gz
linux-f9fa2e2dc0269a54c186a9f6701e20c24b1d67b0.zip
HID: ft260: validate i2c input report length
[ Upstream commit 80c4bbb2b38513e9c3d84805fa61a0ee16d79c45 ] Add two checks to ft260_raw_event() to prevent out-of-bounds reads from malicious or malfunctioning devices: First, reject reports shorter than the 2-byte header (report ID + length fields). Without this, even accessing xfer->length on a 1-byte report is an OOB read. Second, validate xfer->length against the actual data capacity of the received HID report. Each I2C data report ID (0xD0 through 0xDE) defines a different report size in the HID descriptor, so the available payload varies per report. A corrupted length field could cause memcpy to read beyond the report buffer. Reported-by: SebastiƔn JosuƩ Alba Vives <sebasjosue84@gmail.com> Signed-off-by: Michael Zaidman <michael.zaidman@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Stable-dep-of: bf3e39df3a39 ("HID: ft260: fix stack-use-after-return write in I2C read race") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/hid/hid-ft260.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
index 30d7f014df05..2b8db682fa4a 100644
--- a/drivers/hid/hid-ft260.c
+++ b/drivers/hid/hid-ft260.c
@@ -1069,10 +1069,22 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
struct ft260_device *dev = hid_get_drvdata(hdev);
struct ft260_i2c_input_report *xfer = (void *)data;
+ if (size < offsetof(struct ft260_i2c_input_report, data)) {
+ hid_err(hdev, "short report %d\n", size);
+ return -1;
+ }
+
if (xfer->report >= FT260_I2C_REPORT_MIN &&
xfer->report <= FT260_I2C_REPORT_MAX) {
- ft260_dbg("i2c resp: rep %#02x len %d\n", xfer->report,
- xfer->length);
+ ft260_dbg("i2c resp: rep %#02x len %d size %d\n",
+ xfer->report, xfer->length, size);
+
+ if (xfer->length > size -
+ offsetof(struct ft260_i2c_input_report, data)) {
+ hid_err(hdev, "report %#02x: length %d exceeds HID report size\n",
+ xfer->report, xfer->length);
+ return -1;
+ }
if ((dev->read_buf == NULL) ||
(xfer->length > dev->read_len - dev->read_idx)) {