Thread (17 messages) 17 messages, 2 authors, 5d ago

Re: [PATCH v2 10/10] HID: steam: Retry send/recv reports if stale

From: sashiko-bot@kernel.org
Date: 2026-07-07 23:48:40

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] Log spam in expected retry path due to unconditional `hid_err` in `steam_recv_report`.
- [Medium] Out-of-bounds stack read in `hid_dbg` when the device report exceeds the caller's buffer.
- [Medium] `steam_recv_report` reads uninitialized stack memory on short hardware reads.
--
--- Patch [10]: [PATCH v2 10/10] HID: steam: Retry send/recv reports if stale ---
commit 181ac85173536f44d1a324b3bc0042d43fa8238e
Author: Vicki Pfau [off-list ref]

HID: steam: Retry send/recv reports if stale

Sometimes recv report will reply with a stale result from a previous send
report. Instead of failing out, we should retry them, as they generally
reply correctly after three tries, give or take.
quoted hunk ↗ jump to hunk
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 49f6733d89359..ba2dd40a79763 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -497,6 +497,43 @@ static int steam_write_settings(struct steam_device *steam,
 	return steam_recv_report(steam, cmd, 2 + cmd[1]);
 }
 
+static int steam_exchange_report(struct steam_device *steam, u8 *cmd, int csize,
+		u8 *reply, int rsize)
+{
+	unsigned int retries = 5;
+	int ret;
+
+	guard(mutex)(&steam->report_mutex);
+	do {
+		ret = steam_send_report(steam, cmd, csize);
+		if (ret < 0)
+			return ret;
+		ret = steam_recv_report(steam, reply, rsize);
[Severity: Medium]
Does this call cause an out-of-bounds stack read in steam_recv_report()?

When a device sends a padded report that is larger than the caller's buffer
(like the 36-byte reply buffer in steam_get_serial()), steam_recv_report()
copies the correct size but logs using the unbounded ret length:

steam_recv_report() {
    ...
    size = min(size, ret);
    memcpy(data, buf + 1, size);
    ...
    hid_dbg(steam->hdev, "Received report %*ph\n", ret, data);
    ...
}

Since ret can be larger than size, won't hid_dbg() read past the end of the
reply buffer on the stack?

[Severity: Medium]
Can this also result in reading uninitialized stack memory on short reads?

If the hardware sends a short report where hid_hw_raw_request() returns
0 or 1, memcpy() copies 0 bytes, leaving the caller's reply buffer
uninitialized.

steam_recv_report() {
    ...
    if (ret < 2 || ret < data[1] + 2) {
        hid_err(steam->hdev, "%s: expected %u bytes, read %i\n",
                __func__, data[1] + 2, ret);
        return -EPROTO;
    }
}

When ret < 2, data[1] has not been populated. Won't this read and log an
uninitialized byte from the stack?
+		/*
+		 * Sometimes this can fail on the first few tries on the Steam
+		 * Controller (2015). It appears to be a firmware bug, and Steam
+		 * itself just retries, so we should also retry a few times to
+		 * see if we get it.
+		 */
+		if (ret == -EPROTO)
[Severity: Medium]
Will this retry logic cause log spam during normal operation?

Because steam_recv_report() unconditionally calls hid_err() before returning
-EPROTO:

steam_recv_report() {
    ...
    if (ret < 2 || ret < data[1] + 2) {
        hid_err(steam->hdev, "%s: expected %u bytes, read %i\n",
                __func__, data[1] + 2, ret);
        return -EPROTO;
    }
}

Won't every expected retry here flood the kernel log with error messages?
+			continue;
+		if (ret < 0) {
+			hid_err(steam->hdev, "%s: error reading reply (%*ph)\n",
+					__func__, csize, cmd);
+			return ret;
+		}
+		if (reply[0] == cmd[0] && reply[1] >= 1)
+			break;
+		if (retries > 0)
+			continue;
+		hid_err(steam->hdev, "%s: invalid reply (%*ph)\n", __func__,
+				rsize, reply);
+		return -EPROTO;
+	} while (retries--);
+
+	return ret;
+}
-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260707233241.2644971-1-vi@endrift.com?part=10
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help