Skip to content

Commit c04db81

Browse files
committed
net/9p: Fix buffer overflow in USB transport layer
A buffer overflow vulnerability exists in the USB 9pfs transport layer where inconsistent size validation between packet header parsing and actual data copying allows a malicious USB host to overflow heap buffers. The issue occurs because: - usb9pfs_rx_header() validates only the declared size in packet header - usb9pfs_rx_complete() uses req->actual (actual received bytes) for memcpy This allows an attacker to craft packets with small declared size (bypassing validation) but large actual payload (triggering overflow in memcpy). Add validation in usb9pfs_rx_complete() to ensure req->actual does not exceed the buffer capacity before copying data. Reported-by: Yuhao Jiang <[email protected]> Closes: https://lkml.kernel.org/r/[email protected] Fixes: a3be076 ("net/9p/usbg: Add new usb gadget function transport") Cc: [email protected] Message-ID: <[email protected]> Signed-off-by: Dominique Martinet <[email protected]>
1 parent c667c54 commit c04db81

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

net/9p/trans_usbg.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
231231
struct f_usb9pfs *usb9pfs = ep->driver_data;
232232
struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
233233
struct p9_req_t *p9_rx_req;
234+
unsigned int req_size = req->actual;
235+
int status = REQ_STATUS_RCVD;
234236

235237
if (req->status) {
236238
dev_err(&cdev->gadget->dev, "%s usb9pfs complete --> %d, %d/%d\n",
@@ -242,11 +244,19 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
242244
if (!p9_rx_req)
243245
return;
244246

245-
memcpy(p9_rx_req->rc.sdata, req->buf, req->actual);
247+
if (req_size > p9_rx_req->rc.capacity) {
248+
dev_err(&cdev->gadget->dev,
249+
"%s received data size %u exceeds buffer capacity %zu\n",
250+
ep->name, req_size, p9_rx_req->rc.capacity);
251+
req_size = 0;
252+
status = REQ_STATUS_ERROR;
253+
}
254+
255+
memcpy(p9_rx_req->rc.sdata, req->buf, req_size);
246256

247-
p9_rx_req->rc.size = req->actual;
257+
p9_rx_req->rc.size = req_size;
248258

249-
p9_client_cb(usb9pfs->client, p9_rx_req, REQ_STATUS_RCVD);
259+
p9_client_cb(usb9pfs->client, p9_rx_req, status);
250260
p9_req_put(usb9pfs->client, p9_rx_req);
251261

252262
complete(&usb9pfs->received);

0 commit comments

Comments
 (0)