[PATCH v5 10/11] HID: steam: Reject short reads
Vicki Pfau <[email protected]> Wed, 29 Jul 2026 21:12:33 -0700
| Newsgroups | org.kernel.vger.linux-input |
|---|---|
| Message-ID | <[email protected]> |
Steam Controller FEATURE reports encode the size of the message in the
message itself. Previously we were trusting that the size reported matched
the size we actually read, leading to a potential issue with short reads.
Instead, we should actually verify the length of the read.
Fixes: c164d6abf384 ("HID: add driver for Valve Steam Controller")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=75f3f9bff8c510602d36
Signed-off-by: Vicki Pfau <[email protected]>
---
drivers/hid/hid-steam.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index ddd439dd069b..3b4a588c20ad 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -357,6 +357,13 @@ static int steam_recv_report(struct steam_device *steam,
u8 *buf;
int ret;
+ /*
+ * All reports start with a two byte header.
+ * We must read at least two bytes to get a sensible output.
+ */
+ if (size < 2)
+ return -EINVAL;
+
r = steam->hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0];
if (!r) {
hid_err(steam->hdev, "No HID_FEATURE_REPORT submitted - nothing to read\n");
@@ -380,16 +387,30 @@ static int steam_recv_report(struct steam_device *steam,
buf, hid_report_len(r) + 1,
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (ret > 0) {
- ret = min(size, ret - 1);
- memcpy(data, buf + 1, ret);
+ /* Remove the report ID from the return buffer */
+ ret--;
+ size = min(size, ret);
+ memcpy(data, buf + 1, size);
}
kfree(buf);
if (ret < 0)
hid_err(steam->hdev, "%s: error %d\n", __func__, ret);
else
- hid_dbg(steam->hdev, "Received report %*ph\n", ret, data);
- return ret;
+ hid_dbg(steam->hdev, "Received report %*ph\n", size, data);
+ if (ret < 0)
+ return ret;
+
+ if (ret < 2) {
+ hid_err(steam->hdev, "%s: reply too short\n", __func__);
+ return -EPROTO;
+ }
+ if (ret < data[1] + 2) {
+ hid_err(steam->hdev, "%s: expected %u bytes, read %i\n",
+ __func__, data[1] + 2, ret);
+ return -EPROTO;
+ }
+ return size;
}
static int steam_send_report(struct steam_device *steam,
--
2.54.0