All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jann Horn <jannh@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jakob Koschel <jakobkoschel@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-kernel@vger.kernel.org, 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 01/13] list: introduce speculative safe list_for_each_entry()
Date: Fri, 18 Feb 2022 17:29:50 +0100	[thread overview]
Message-ID: <CAG48ez2OgMThMd_EDA=ekFXy5=sWYmLuSshj1jiMvzpuy84M2Q@mail.gmail.com> (raw)
In-Reply-To: <Yg6iCS0XZB6EtMP7@kroah.com>

On Thu, Feb 17, 2022 at 8:29 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> On Thu, Feb 17, 2022 at 07:48:17PM +0100, Jakob Koschel wrote:
> > list_for_each_entry() selects either the correct value (pos) or a safe
> > value for the additional mispredicted iteration (NULL) for the list
> > iterator.
> > list_for_each_entry() calls select_nospec(), which performs
> > a branch-less select.
[...]
> >  #define list_for_each_entry(pos, head, member)                               \
> >       for (pos = list_first_entry(head, typeof(*pos), member);        \
> > -          !list_entry_is_head(pos, head, member);                    \
> > +         ({ bool _cond = !list_entry_is_head(pos, head, member);     \
> > +          pos = select_nospec(_cond, pos, NULL); _cond; }); \
> >            pos = list_next_entry(pos, member))
> >
>
> You are not "introducing" a new macro for this, you are modifying the
> existing one such that all users of it now have the select_nospec() call
> in it.
>
> Is that intentional?  This is going to hit a _lot_ of existing entries
> that probably do not need it at all.
>
> Why not just create list_for_each_entry_nospec()?

My understanding is that almost all uses of `list_for_each_entry()`
currently create type-confused "pos" pointers when they terminate.

(As a sidenote, I've actually seen this lead to a bug in some
out-of-tree code in the past, where someone had a construct like this:

list_for_each_entry(element, ...) {
  if (...)
    break; /* found the element we were looking for */
}
/* use element here */

and then got a "real" type confusion bug from that when no matching
element was found.)

*Every time* you have a list_for_each_entry() iteration over some list
where the list_head that you start from is not embedded in the same
struct as the element list_heads (which is the normal case), and you
don't break from the iteration early, a bogus type-confused pointer
(which might not even be part of the same object as the real list
head, but instead some random out-of-bounds memory in front of it) is
assigned to "pos" (which I think is probably already a violation of
the C standard, but whatever), and this means that almost every
list_for_each_entry() loop ends with a branch that, when
misspeculated, leads to speculative accesses to a type-confused
pointer.

And once you're speculatively accessing type-confused pointers, and
especially if you start writing to them or loading more pointers from
them, it's really hard to reason about what might happen, just like
with "normal" type confusion bugs.


If we don't want to keep this performance hit, then in the long term
it might be a good idea to refactor away the (hideous) idea that the
head of a list and its elements are exactly the same type and
everything's just one big circular thing. Then we could change the
data structures so that this speculative confusion can't happen
anymore and avoid this explicit speculation avoidance on list
iteration.

But for now, I think we probably need this.

  reply	other threads:[~2022-02-18 16:30 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 [this message]
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
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='CAG48ez2OgMThMd_EDA=ekFXy5=sWYmLuSshj1jiMvzpuy84M2Q@mail.gmail.com' \
    --to=jannh@google.com \
    --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=gregkh@linuxfoundation.org \
    --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.