diff options
| author | Michael Zaidman <michael.zaidman@gmail.com> | 2026-04-11 09:24:37 +0300 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.com> | 2026-04-28 19:24:52 +0300 |
| commit | 80c4bbb2b38513e9c3d84805fa61a0ee16d79c45 (patch) | |
| tree | 7ed535d7db2594a47b9cc3073f226e345ae6b5ad | |
| parent | 278dd0487907112de8e34e1a97ac6145a8081523 (diff) | |
| download | linux-80c4bbb2b38513e9c3d84805fa61a0ee16d79c45.tar.xz | |
HID: ft260: validate i2c input report length
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>
| -rw-r--r-- | drivers/hid/hid-ft260.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c index 333341e80b0e..70e2eedb465a 100644 --- a/drivers/hid/hid-ft260.c +++ b/drivers/hid/hid-ft260.c @@ -1068,10 +1068,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)) { |
