]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: gadget: aspeed_udc: avoid past-the-end iterator in dequeue
authorMaoyi Xie <maoyixie.tju@gmail.com>
Thu, 21 May 2026 06:54:28 +0000 (14:54 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 May 2026 09:36:01 +0000 (11:36 +0200)
ast_udc_ep_dequeue() declares the loop cursor `req` outside the
list_for_each_entry(). After the loop it tests `&req->req != _req`
to decide whether the request was found. If the queue holds no
match, `req` is past-the-end. It then aliases
container_of(&ep->queue, struct ast_udc_request, queue) via offset
cancellation. Whether that synthetic address equals `_req` depends
on heap layout. The function can return 0 without dequeueing
anything.

Default `rc` to -EINVAL and set it to 0 only inside the match
branch. `req` is no longer read after the loop, so the past-the-end
dereference goes away. No extra cursor variable or post-loop test
is needed.

Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Suggested-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://patch.msgid.link/20260521065428.3261238-1-maoyixie.tju@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/udc/aspeed_udc.c

index 7fc6696b7694b6d38349b59690670941c0c5e047..75f9c831b21a62f1cadd2b56febfaa703bf138d3 100644 (file)
@@ -694,7 +694,7 @@ static int ast_udc_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
        struct ast_udc_dev *udc = ep->udc;
        struct ast_udc_request *req;
        unsigned long flags;
-       int rc = 0;
+       int rc = -EINVAL;
 
        spin_lock_irqsave(&udc->lock, flags);
 
@@ -704,14 +704,11 @@ static int ast_udc_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
                        list_del_init(&req->queue);
                        ast_udc_done(ep, req, -ESHUTDOWN);
                        _req->status = -ECONNRESET;
+                       rc = 0;
                        break;
                }
        }
 
-       /* dequeue request not found */
-       if (&req->req != _req)
-               rc = -EINVAL;
-
        spin_unlock_irqrestore(&udc->lock, flags);
 
        return rc;