Skip to contentSkip to conversation

usb: host: ehci-sched: Fix potential out-of-bounds access of bandwidth[]

PATCH In review [email protected] 2 participants 2 messages May 4

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: host: ehci-sched: Fix potential out-of-bounds access of bandwidth[]

From: Denis Rastyogin <[email protected]>

The microframe index used to access the bandwidth array is not properly bounded. Although it is masked to a limited range, subsequent loop iterations can advance it beyond the end of the array, leading to an out-of-bounds access.

This can happen when sitd_slot_ok() is called from iso_stream_schedule() with period = stream->uperiod = 1024. In that case, the loop may reach sitd_slot_ok() with start = 1981, resulting in uframe = 61. After three iterations, the index exceeds the array bounds.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes d0ce5c6b9208 ("USB: EHCI: use a bandwidth-allocation table")
---
 drivers/usb/host/ehci-sched.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/usb/host/ehci-sched.c +2 -0
index a241337c9af8..d2bace03b8c9 100644
@@ -1429,6 +1429,8 @@ sitd_slot_ok(
 		uf = uframe;
 		max_used = ehci->uframe_periodic_max - stream->ps.usecs;
 		for (tmp = stream->ps.cs_mask & 0xff; tmp; tmp >>= 1, uf++) {
+			if (uf >= EHCI_BANDWIDTH_SIZE)
+				return 0;
 			if (ehci->bandwidth[uf] > max_used)
 				return 0;
 		}
Signature · 1 line
2.42.2
maintainer
#1 lore raw
Quoted 6 lines · On Mon, May 04, 2026 at 02:43:40PM +0300, [email protected] wrote:

From: Denis Rastyogin <[email protected]>

The microframe index used to access the bandwidth array is not properly bounded. Although it is masked to a limited range, subsequent loop iterations can advance it beyond the end of the array, leading to an out-of-bounds access.

I don't think so.

Quoted 18 lines

This can happen when sitd_slot_ok() is called from iso_stream_schedule() with period = stream->uperiod = 1024. In that case, the loop may reach sitd_slot_ok() with start = 1981, resulting in uframe = 61. After three iterations, the index exceeds the array bounds.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes d0ce5c6b9208 ("USB: EHCI: use a bandwidth-allocation table")
---
 drivers/usb/host/ehci-sched.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/usb/host/ehci-sched.c +0 -0
index a241337c9af8..d2bace03b8c9 100644

drivers/usb/host/ehci-sched.c sitd_slot_ok( · line 1431

Quoted 3 lines
drivers/usb/host/ehci-sched.c +0 -0
@@ -1429,6 +1429,8 @@ sitd_slot_ok(
 		uf = uframe;
 		max_used = ehci->uframe_periodic_max - stream->ps.usecs;
 		for (tmp = stream->ps.cs_mask & 0xff; tmp; tmp >>= 1, uf++) {

You (and SVACE) missed the fact that the loop will end when tmp becomes
0. And thanks to this test earlier in the function:

	/* for OUT, don't wrap SSPLIT into H-microframe 7 */
	if (((stream->ps.cs_mask & 0xff) << (uframe & 7)) >= (1 << 7))
		return 0;

tmp will become 0 at or before the fourth iteration.

Alan Stern

Quoted 7 lines
drivers/usb/host/ehci-sched.c +2 -0
+			if (uf >= EHCI_BANDWIDTH_SIZE)
+				return 0;
 			if (ehci->bandwidth[uf] > max_used)
 				return 0;
 		}
Signature · 1 line
2.42.2