summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2026-06-16 17:36:17 +0700
committerGitHub <[email protected]>2026-06-16 17:36:17 +0700
commit7b791916a702c28f8f39e9bfc5eb8455d0942865 (patch)
treed9e540eac87cb26beb5b14b2aa3d396993a2090e /src/device
parent14e20e9f6b592d63bb18eb6fb36f1fd462f4f0a0 (diff)
device: clamp EP0 OUT data copy to the control transfer buffer (#3705)
* device: clamp EP0 OUT data copy to the control transfer buffer usbd_control_xfer_cb() copied xferred_bytes from the EP0 bounce buffer into the requester's buffer with no bound. A non-compliant host that sends an OUT data packet larger than the control transfer's data_len (= min(len, wLength), the buffer capacity) would overflow that buffer and over-count total_xferred. Clamp xferred_bytes to the remaining buffer space before the memcpy and accounting.
Diffstat (limited to 'src/device')
-rw-r--r--src/device/usbd.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 55ad330c1..f87b63111 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -914,6 +914,8 @@ static bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t
// Data stage progress
if (ctrl_xfer->request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
TU_VERIFY(ctrl_xfer->buffer);
+ // Clamp host overrun to remaining capacity (data_len) so memcpy can't overflow the caller buffer
+ xferred_bytes = tu_min32(xferred_bytes, ctrl_xfer->data_len - ctrl_xfer->total_xferred);
if (ctrl_xfer->buffer != _ctrl_epbuf.buf) {
memcpy(ctrl_xfer->buffer, _ctrl_epbuf.buf, xferred_bytes);
}