All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Jakob <jakobkoschel@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-arch <linux-arch@vger.kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Arnd Bergman <arnd@arndb.de>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Kees Cook <keescook@chromium.org>,
	Mike Rapoport <rppt@kernel.org>,
	"Gustavo A. R. Silva" <gustavo@embeddedor.com>,
	Brian Johannesmeyer <bjohannesmeyer@gmail.com>,
	Cristiano Giuffrida <c.giuffrida@vu.nl>,
	"Bos, H.J." <h.j.bos@vu.nl>
Subject: Re: [RFC PATCH 03/13] usb: remove the usage of the list iterator after the loop
Date: Thu, 24 Feb 2022 11:33:52 +0100	[thread overview]
Message-ID: <YhdfEIwI4EdtHdym@kroah.com> (raw)
In-Reply-To: <86C4CE7D-6D93-456B-AA82-F8ADEACA40B7@gmail.com>

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 <jakobkoschel@gmail.com>
> ---
> 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;
 	}

  reply	other threads:[~2022-02-24 10:34 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-17 18:48 [RFC PATCH 00/13] Proposal for speculative safe list iterator Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 01/13] list: introduce speculative safe list_for_each_entry() Jakob Koschel
2022-02-17 19:29   ` Greg Kroah-Hartman
2022-02-18 16:29     ` Jann Horn
2022-02-18 16:29   ` Jann Horn
2022-02-23 14:32     ` Jakob
2022-02-19 19:44   ` Jann Horn
2022-02-17 18:48 ` [RFC PATCH 02/13] scripts: coccinelle: adapt to find list_for_each_entry nospec issues Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 03/13] usb: remove the usage of the list iterator after the loop Jakob Koschel
2022-02-17 19:28   ` Linus Torvalds
2022-02-23 14:13     ` Jakob
2022-02-23 14:16       ` Jakob
2022-02-24 10:33         ` Greg Kroah-Hartman [this message]
2022-02-24 17:56           ` Linus Torvalds
     [not found]         ` <6d191223d93249a98511177d4af08420@pexch012b.vu.local>
2022-02-24 10:46           ` Cristiano Giuffrida
2022-02-24 11:26             ` Greg Kroah-Hartman
2022-02-23 18:47       ` Linus Torvalds
2022-02-23 19:23         ` Linus Torvalds
2022-02-23 19:43           ` Linus Torvalds
2022-02-23 20:24           ` Arnd Bergmann
2022-02-23 20:43             ` Linus Torvalds
2022-02-23 20:48               ` Arnd Bergmann
2022-02-23 21:53                 ` Linus Torvalds
2022-02-24 16:04                   ` Nathan Chancellor
2022-02-23 20:54               ` Linus Torvalds
2022-02-23 22:21                 ` David Laight
2022-02-25 21:36                 ` Uecker, Martin
2022-02-25 22:02                   ` Linus Torvalds
2022-02-26  1:21                     ` Martin Uecker
2022-02-27 18:12                       ` Miguel Ojeda
2022-02-28  7:08                         ` Martin Uecker
2022-02-28 13:49                           ` Miguel Ojeda
2022-03-01 20:26                             ` Linus Torvalds
2022-03-02  7:27                               ` Martin Uecker
2022-02-26 12:42           ` Segher Boessenkool
2022-02-26 22:14             ` Arnd Bergmann
2022-02-26 23:03               ` Linus Torvalds
2022-02-27  1:19                 ` Segher Boessenkool
2022-02-27  1:09               ` Segher Boessenkool
2022-02-27  7:10                 ` David Laight
2022-02-27 11:32                   ` Segher Boessenkool
2022-02-27 18:09                     ` Miguel Ojeda
2022-02-27 20:17                       ` Segher Boessenkool
2022-02-27 21:04                         ` Linus Torvalds
2022-02-28  6:15                           ` David Laight
2022-02-27 22:43                         ` Miguel Ojeda
2022-02-27 21:28                 ` Arnd Bergmann
2022-02-27 22:43                   ` Segher Boessenkool
2022-02-17 18:48 ` [RFC PATCH 04/13] vfio/mdev: " Jakob Koschel
2022-02-18 15:12   ` Jason Gunthorpe
2022-02-23 14:18     ` Jakob
2022-02-23 19:06       ` Linus Torvalds
2022-02-23 19:12         ` Jason Gunthorpe
2022-02-23 19:31           ` Linus Torvalds
2022-02-23 20:15             ` Jakob
2022-02-23 20:22               ` Linus Torvalds
2022-02-23 22:08                 ` Jakob
2022-02-23 20:19             ` Rasmus Villemoes
2022-02-23 20:34               ` Linus Torvalds
2022-02-17 18:48 ` [RFC PATCH 05/13] drivers/perf: " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 06/13] ARM: mmp: " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 07/13] udp_tunnel: " Jakob Koschel
2022-02-23 20:00   ` Christophe JAILLET
2022-02-24  6:20     ` Dan Carpenter
2022-02-17 18:48 ` [RFC PATCH 08/13] net: dsa: future proof usage of " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 09/13] drbd: " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 10/13] powerpc/spufs: " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 11/13] ath6kl: remove use " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 12/13] staging: greybus: audio: Remove usage " Jakob Koschel
2022-02-17 18:48 ` [RFC PATCH 13/13] scsi: mpt3sas: comment about invalid usage of the list iterator Jakob Koschel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YhdfEIwI4EdtHdym@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=arnd@arndb.de \
    --cc=bjohannesmeyer@gmail.com \
    --cc=c.giuffrida@vu.nl \
    --cc=gustavo@embeddedor.com \
    --cc=h.j.bos@vu.nl \
    --cc=jakobkoschel@gmail.com \
    --cc=keescook@chromium.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rppt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.