It is unsafe to assume that &req->req != _req can only evaluate to false if the break within the list iterator is hit. When the break is not hit, req is set to an address derived from the head element. If _req would match with that value of req it would allow continuing beyond the safety check even if the _req was never found within the list. Signed-off-by: Jakob Koschel <jakobkoschel@xxxxxxxxx> --- drivers/usb/gadget/udc/gr_udc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 4b35739d3695..18ae2c7a1656 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1695,6 +1695,7 @@ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) struct gr_udc *dev; int ret = 0; unsigned long flags; + bool found = false; ep = container_of(_ep, struct gr_ep, ep); if (!_ep || !_req || (!ep->ep.desc && ep->num != 0)) @@ -1711,10 +1712,12 @@ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) /* Make sure it's actually queued on this endpoint */ list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) + if (&req->req == _req) { + found = true; break; + } } - if (&req->req != _req) { + if (!found) { ret = -EINVAL; goto out; } -- 2.25.1