Received: by 2002:a05:6a10:9afc:0:0:0:0 with SMTP id t28csp1469460pxm; Thu, 24 Feb 2022 03:56:14 -0800 (PST) X-Google-Smtp-Source: ABdhPJzTc6SJwosgIuy/QQVCIQNuHvbafde9Aipjg7KkUyJ3n/YuPmmJ6L3UQhWeL8K9vZgEygPZ X-Received: by 2002:a17:906:82cf:b0:6d0:3d6:8f27 with SMTP id a15-20020a17090682cf00b006d003d68f27mr1945734ejy.236.1645703773736; Thu, 24 Feb 2022 03:56:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645703773; cv=none; d=google.com; s=arc-20160816; b=cg3AVZWGlZL/tYA9AldqkzzhK0vHQLZWf0QnglDwSZWoFcxfQCnhaf98RItKZAVicB SQ7atWI79FmEnfOz+7/e91fGMNupT4Ik5L4uVEYdwPCklgowHiU04iaTnGwbAusO8Hee LNXcN1tjf1b2tsemWWQjZLrKElnuYb+cYZseE56BJHXEyyXJv0pMH7fPnd3KCdYlV7mk gLwAg6XKgtmbX2uI9vHkfWZ9b26Q/Ww8ADLcxkvv3RwU3wm42sJpvLVa9KhOCu+80qAp hfK+xerx558TwmSlHliY56tvhurNs7bdHUwsa6QVZDOhowcHMf6QVCschpE+dtWpjcMl esqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=GKKPmqJDD3BP1jz651MFwHNCrcyQryuRs+l/mu8tz9c=; b=ZD1xmr+KPPk4Os4pdMwbzxqpw6fJMC4SHiuhDO34a8OTOad9wb6fwgeqFiENkYElUs 74InaLuQ3cmjqTylehnnMrYFSjS87XQNZH0WkjkIXZx0una96VxAu8L6SbqcC0QAeyoS W22+AlN8eNT1bIJ+cRuORAA8YMaEg4yfZVTW5eY6RRKAJC87UV3m/q849FOK5rrZVsMD dVzVgglbwguIt35oxI+YT/LP9ZyCAKix65P1TFYTVDgJRoFn7mdWlll/CuwZJ+xBnDbF opV8FLaE8KYYALWFjOcP2sL+Cd7ahSJzesYxLeWRDDMFHrrMC9O8F+bHupKD5UtAeMun 2/zA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=SuXeo0uT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g2si1246642edq.450.2022.02.24.03.55.39; Thu, 24 Feb 2022 03:56:13 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=SuXeo0uT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233482AbiBXKe1 (ORCPT + 99 others); Thu, 24 Feb 2022 05:34:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230147AbiBXKe0 (ORCPT ); Thu, 24 Feb 2022 05:34:26 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88E8028DDFD; Thu, 24 Feb 2022 02:33:56 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 246756166A; Thu, 24 Feb 2022 10:33:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08BB5C340E9; Thu, 24 Feb 2022 10:33:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1645698835; bh=lzWyFdL31RKE3zQVYxiJ04dyKxK6IDEAx7DqCxzEvLk=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=SuXeo0uTHBEsHEZqV/bw4+zKtzE6dvT7tUVWBC8PNQ/ccPXTmC4MyeOIu8M8cdEXG FpqPBxMO7lhWOjpFerqJAPdZcjklhi7suxJ4pDv76WKJ5+gmPIjhUaKuAXHBy8T4aD LvSVaaiFqFnU6d1qNW4O3aaf0dmQUW3f958cY3Wg= Date: Thu, 24 Feb 2022 11:33:52 +0100 From: Greg Kroah-Hartman To: Jakob Cc: Linus Torvalds , Linux Kernel Mailing List , linux-arch , Thomas Gleixner , Arnd Bergman , Andy Shevchenko , Andrew Morton , Kees Cook , Mike Rapoport , "Gustavo A. R. Silva" , Brian Johannesmeyer , Cristiano Giuffrida , "Bos, H.J." Subject: Re: [RFC PATCH 03/13] usb: remove the usage of the list iterator after the loop Message-ID: References: <20220217184829.1991035-1-jakobkoschel@gmail.com> <20220217184829.1991035-4-jakobkoschel@gmail.com> <6DFD3D91-B82C-469C-8771-860C09BD8623@gmail.com> <86C4CE7D-6D93-456B-AA82-F8ADEACA40B7@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <86C4CE7D-6D93-456B-AA82-F8ADEACA40B7@gmail.com> X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Feb 23, 2022 at 03:16:09PM +0100, Jakob wrote: > Note that I changed the location of the struct member 'req' in gr_request > to make this work. Instead of reshuffling struct members this can also be > introduced by simply adding new struct members in certain spots. > In other code locations with the same pattern I didn't have to do that. > > Assuming '_req' passed to gr_dequeue() is located just past 'ep' on the > heap, the check could pass even though the list searched is completely > empty. > > &req->req for the head element will be an out-of-bounds pointer > that by coincidence or heap massaging is where '_req' is located. > > Even if the list is empty the list_for_each_entry() macro will do: > > pos = list_first_entry(head, typeof(*pos), member); > > resolving all the macros (list_first_entry() etc) it will look like this: > > pos = container_of(head->next, typeof(*pos), member) > > Since the list is empty head->next == head and container_of() is called on something > that is *not* actually of type gr_request. > > Next, the check if the end of the loop is hit is evaluated: > > !list_entry_is_head(pos, head, member); > > which will stop the loop directly before executing a single iteration. > > then using '&req->req' is some bogus pointer pointing just past the struct gr_ep, > where in this case '_req' is located. > > The point I'm trying to make: it's probably not safe to rely on the compiler and > that everyone is aware of this risk when adding/removing/reordering struct members. > > > Signed-off-by: Jakob Koschel > --- > drivers/usb/gadget/udc/gr_udc.c | 25 +++++++++++++++++++++++++ > drivers/usb/gadget/udc/gr_udc.h | 2 +- > 2 files changed, 26 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c > index 4b35739d3695..29c662f28428 100644 > --- a/drivers/usb/gadget/udc/gr_udc.c > +++ b/drivers/usb/gadget/udc/gr_udc.c > @@ -1718,6 +1718,7 @@ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) > ret = -EINVAL; > goto out; > } > + printk(KERN_INFO "JKL: This does print, but shouldn't"); > > if (list_first_entry(&ep->queue, struct gr_request, queue) == req) { > /* This request is currently being processed */ > @@ -1739,6 +1740,30 @@ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) > return ret; > } > > +static int __init init_test_jkl3(void) > +{ > + struct gr_ep *ep; > + struct gr_udc *dev; > + struct usb_request *_req; > + void *buffer; > + > + /* assume the usb_request struct is located just after the 'ep' on the heap */ > + buffer = kzalloc(sizeof(struct gr_ep)+sizeof(struct usb_request), GFP_KERNEL); > + ep = buffer; > + _req = buffer+sizeof(struct gr_ep); > + > + /* setup to call gr_dequeue() */ > + dev = kzalloc(sizeof(struct gr_udc), GFP_KERNEL); > + ep->dev = dev; > + ep->dev->driver = 1; > + INIT_LIST_HEAD(&ep->queue); /* list is empty */ > + > + gr_dequeue(&ep->ep, _req); > + > + return 0; > +} > +__initcall(init_test_jkl3); > + > /* Helper for gr_set_halt and gr_set_wedge */ > static int gr_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) > { > diff --git a/drivers/usb/gadget/udc/gr_udc.h b/drivers/usb/gadget/udc/gr_udc.h > index 70134239179e..14a18d5b5cf8 100644 > --- a/drivers/usb/gadget/udc/gr_udc.h > +++ b/drivers/usb/gadget/udc/gr_udc.h > @@ -159,7 +159,6 @@ struct gr_ep { > }; > > struct gr_request { > - struct usb_request req; > struct list_head queue; > > /* Chain of dma descriptors */ > @@ -171,6 +170,7 @@ struct gr_request { > u16 oddlen; /* Size of odd length tail if buffer length is "odd" */ > > u8 setup; /* Setup packet */ > + struct usb_request req; > }; > > enum gr_ep0state { > -- > 2.25.1 So, to follow the proposed solution in this thread, the following change is the "correct" one to make, right? diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 4b35739d3695..5d65d8ad5281 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1690,7 +1690,8 @@ static int gr_queue_ext(struct usb_ep *_ep, struct usb_request *_req, /* Dequeue JUST ONE request */ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) { - struct gr_request *req; + struct gr_request *req = NULL; + struct gr_request *tmp; struct gr_ep *ep; struct gr_udc *dev; int ret = 0; @@ -1710,11 +1711,13 @@ static int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(&dev->lock, flags); /* Make sure it's actually queued on this endpoint */ - list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) + list_for_each_entry(tmp, &ep->queue, queue) { + if (&tmp->req == _req) { + req = tmp; break; + } } - if (&req->req != _req) { + if (!req) { ret = -EINVAL; goto out; }