2021-05-01 16:28:42

by Andy Lutomirski

[permalink] [raw]
Subject: Do we need to do anything about "dead µops?"

Hi all-

The "I See Dead µops" paper that is all over the Internet right now is
interesting, and I think we should discuss the extent to which we
should do anything about it. I think there are two separate issues:

First, should we (try to) flush the µop cache across privilege
boundaries? I suspect we could find ways to do this, but I don't
really see the point. A sufficiently capable attacker (i.e. one who
can execute their own code in the dangerous speculative window or one
who can find a capable enough string of gadgets) can put secrets into
the TLB, various cache levels, etc. The µop cache is a nice piece of
analysis, but I don't think it's qualitatively different from anything
else that we don't flush. Am I wrong?

Second, the authors claim that their attack works across LFENCE. I
think that this is what's happening:

load secret into %rax
lfence
call/jmp *%rax

As I understand it, on CPUs from all major vendors, the call/jmp will
gladly fetch before lfence retires, but the address from which it
fetches will come from the branch predictors, not from the
speculatively computed value in %rax. So this is nothing new. If the
kernel leaks a secret into the branch predictors, we have already
mostly lost, although we have a degree of protection from the various
flushes we do. In other words, if we do:

load secret into %rax
<-- non-speculative control flow actually gets here
lfence
call/jmp *%rax

then we will train our secret into the predictors but also leak it
into icache, TLB, etc, and we already lose. We shouldn't be doing
this in a way that matters. But, if we do:

mispredicted branch
load secret into %rax
<-- this won't retire because the branch was mispredicted
lfence
<-- here we're fetching but not dispatching
call/jmp *%rax

then the leak does not actually occur unless we already did the
problematic scenario above.

So my tentative analysis is that no action on Linux's part is required.

What do you all think?

--Andy


2021-05-03 23:31:01

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Do we need to do anything about "dead µops?"

On Sat, May 01, 2021 at 09:26:33AM -0700, Andy Lutomirski wrote:
> Hi all-
>
> The "I See Dead µops" paper that is all over the Internet right now is
> interesting, and I think we should discuss the extent to which we
> should do anything about it. I think there are two separate issues:
>
> First, should we (try to) flush the µop cache across privilege
> boundaries? I suspect we could find ways to do this, but I don't
> really see the point. A sufficiently capable attacker (i.e. one who
> can execute their own code in the dangerous speculative window or one
> who can find a capable enough string of gadgets) can put secrets into
> the TLB, various cache levels, etc. The µop cache is a nice piece of
> analysis, but I don't think it's qualitatively different from anything
> else that we don't flush. Am I wrong?

Wouldn't this type of gadget (half-v1 gadget + value-dependent-branch)
would be much more likely to occur than a traditional Spectre v1
(half-v1 gadget + value-addressed-load)?

Also, in section V.A., they identified 37 gadgets. Has anybody looked
at those yet?

(And this makes me realize my uaccess pointer masking patch [1] never
got merged...)

[1] https://lore.kernel.org/lkml/1d06ed6485b66b9f674900368b63d7ef79f666ca.1599756789.git.jpoimboe@redhat.com/

--
Josh

2021-05-04 01:53:16

by Andy Lutomirski

[permalink] [raw]
Subject: Re: Do we need to do anything about "dead µops?"

On Mon, May 3, 2021 at 4:30 PM Josh Poimboeuf <[email protected]> wrote:
>
> On Sat, May 01, 2021 at 09:26:33AM -0700, Andy Lutomirski wrote:
> > Hi all-
> >
> > The "I See Dead µops" paper that is all over the Internet right now is
> > interesting, and I think we should discuss the extent to which we
> > should do anything about it. I think there are two separate issues:
> >
> > First, should we (try to) flush the µop cache across privilege
> > boundaries? I suspect we could find ways to do this, but I don't
> > really see the point. A sufficiently capable attacker (i.e. one who
> > can execute their own code in the dangerous speculative window or one
> > who can find a capable enough string of gadgets) can put secrets into
> > the TLB, various cache levels, etc. The µop cache is a nice piece of
> > analysis, but I don't think it's qualitatively different from anything
> > else that we don't flush. Am I wrong?
>
> Wouldn't this type of gadget (half-v1 gadget + value-dependent-branch)
> would be much more likely to occur than a traditional Spectre v1
> (half-v1 gadget + value-addressed-load)?

I don't fully believe this. It's certainly the case that:

if (mispredicted as false)
return;
secret = some_secret();
if (secret == 42)
do_something();

will leak the fact that the secret is 42 into the µop cache, but it
will also leak it into the icache and lots of other things. I see
nothing new here. That being said, it's probably still worth
investigating the gadgets.

>
> Also, in section V.A., they identified 37 gadgets. Has anybody looked
> at those yet?

Not I.

2021-05-04 03:18:27

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Do we need to do anything about "dead µops?"

On Mon, May 03, 2021 at 06:31:21PM -0700, Andy Lutomirski wrote:
> On Mon, May 3, 2021 at 4:30 PM Josh Poimboeuf <[email protected]> wrote:
> >
> > On Sat, May 01, 2021 at 09:26:33AM -0700, Andy Lutomirski wrote:
> > > Hi all-
> > >
> > > The "I See Dead µops" paper that is all over the Internet right now is
> > > interesting, and I think we should discuss the extent to which we
> > > should do anything about it. I think there are two separate issues:
> > >
> > > First, should we (try to) flush the µop cache across privilege
> > > boundaries? I suspect we could find ways to do this, but I don't
> > > really see the point. A sufficiently capable attacker (i.e. one who
> > > can execute their own code in the dangerous speculative window or one
> > > who can find a capable enough string of gadgets) can put secrets into
> > > the TLB, various cache levels, etc. The µop cache is a nice piece of
> > > analysis, but I don't think it's qualitatively different from anything
> > > else that we don't flush. Am I wrong?
> >
> > Wouldn't this type of gadget (half-v1 gadget + value-dependent-branch)
> > would be much more likely to occur than a traditional Spectre v1
> > (half-v1 gadget + value-addressed-load)?
>
> I don't fully believe this. It's certainly the case that:
>
> if (mispredicted as false)
> return;
> secret = some_secret();
> if (secret == 42)
> do_something();

Well, obviously we should never write secret-protecting code in that
manner.

I was actually thinking more along the lines of

val = 0;

if (user_supplied_idx < ARRAY_SIZE) // trained to speculatively be 'true'
val = boring_non_secret_array[user_supplied_idx];

if (val & 1)
do_something();

In other words, the victim code wouldn't be accessing the secret
intentionally. So there's no reason for it to avoid doing
data-dependent branches.

> will leak the fact that the secret is 42 into the µop cache, but it
> will also leak it into the icache and lots of other things. I see
> nothing new here.

Hm, I suppose. I don't think I'd ever considered that vector though.

All the more reason to mask usercopy addresses...

--
Josh

2021-05-04 14:27:53

by David Laight

[permalink] [raw]
Subject: RE: Do we need to do anything about "dead µo ps?"

From: Josh Poimboeuf
> Sent: 04 May 2021 04:16
...
> I was actually thinking more along the lines of
>
> val = 0;
>
> if (user_supplied_idx < ARRAY_SIZE) // trained to speculatively be 'true'
> val = boring_non_secret_array[user_supplied_idx];
>
> if (val & 1)
> do_something();
>
> In other words, the victim code wouldn't be accessing the secret
> intentionally. So there's no reason for it to avoid doing
> data-dependent branches.

Isn't that one of the very boring standard spectre cases?

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

2021-05-04 15:03:09

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Do we need to do anything about "dead µops?"

On Tue, May 04, 2021 at 01:06:06PM +0000, David Laight wrote:
> From: Josh Poimboeuf
> > Sent: 04 May 2021 04:16
> ...
> > I was actually thinking more along the lines of
> >
> > val = 0;
> >
> > if (user_supplied_idx < ARRAY_SIZE) // trained to speculatively be 'true'
> > val = boring_non_secret_array[user_supplied_idx];
> >
> > if (val & 1)
> > do_something();
> >
> > In other words, the victim code wouldn't be accessing the secret
> > intentionally. So there's no reason for it to avoid doing
> > data-dependent branches.
>
> Isn't that one of the very boring standard spectre cases?

Classic v1 as described in the Spectre paper was a data-dependent
load/store, not a data-dependent branch.

--
Josh