
V8: A Year with Spectre - tosh
https://v8.dev/blog/spectre
======
samth
_Like many with a background in programming languages and their
implementations, the idea that safe languages enforce a proper abstraction
boundary, not allowing well-typed programs to read arbitrary memory, has been
a guarantee upon which our mental models have been built. It is a depressing
conclusion that our models were wrong — this guarantee is not true on today’s
hardware. Of course, we still believe that safe languages have great
engineering benefits and will continue to be the basis for the future, but… on
today’s hardware they leak a little._

We should all be more angry at chip makers for this. Intel isn't willing to
admit that they broke things because then they'd have to fix it, but we
shouldn't accept that kind of approach.

~~~
TheSoftwareGuy
Everybody who studied even a little bit about processor hardware new about
speculative execution. And it was never just intel that was using it, (they
all were). Until Spectre that technology was not considered controversial.

the crazy thing is that nobody saw this until recently.

~~~
samth
"Until event X, doing <thing that X demonstrated was bad> was not considered
controversial" is an explanation of behavior, but not really a defense.

~~~
rayiner
Here, chip makers never promised to prevent X. Maybe preventing X is desirable
now that people do Y, but you can hardly blame them for not preventing
something they didn’t promise to prevent.

~~~
shawnz
They promised to develop general purpose chips which can meet as many desktop
computing needs as possible, which now implicitly includes need Y (but they
didn't anticipate that at the time).

They could of course just reject the necessity of need Y, but if the majority
of their clients actually do have need Y, can it really be said that the chip
is successful at being general purpose?

~~~
rat9988
Yeah you can. Because the chip provides capabilities so you can do such
protections in software if you want, or get more speed if you don't want.

------
jcranmer
When Spectre first came out, my prediction was basically that the only
effective mitigation would be to move the untrusted code into another address
space. This post reinforces that they have exhausted all other options:

> Our research reached the conclusion that, in principle, untrusted code can
> read a process’s entire address space using Spectre and side channels.
> Software mitigations reduce the effectiveness of many potential gadgets, but
> are not efficient or comprehensive. The only effective mitigation is to move
> sensitive data out of the process’s address space.

Probably the most effective hardware mitigation would be to shift the
isolation to a page-level granularity, so that you could say that speculation
is disabled for memory in specific pages.

~~~
kllrnohj
> Probably the most effective hardware mitigation would be to shift the
> isolation to a page-level granularity, so that you could say that
> speculation is disabled for memory in specific pages.

What's wrong with the hardware mitigation of just using multiple processes? It
already exists, it already works, and it already has decades of tooling &
infrastructure built around it.

~~~
sievebrain
It's very expensive. Site isolation in Chrome explodes memory pressure on the
system. Language enforced confidentiality is a lot less resource intensive.

~~~
kllrnohj
> It's very expensive.

Processes? They don't need to be expensive, as proven by Linux. Trivially
cheap enough to do one per site origin in a browser, anyway.

> Site isolation in Chrome explodes memory pressure on the system.

How do you figure? Code pages are shared, after all. Only duplicate heap would
be an issue, but shared memory exists and can mitigate that if there's read-
only data to be shared.

So what memory pressure is "exploded"?

> Language enforced confidentiality is a lot less resource intensive.

Not at all clear-cut or self-supporting. What resource(s) is it less intensive
on, and what are you using to support such a claim?

CPU time is a resource, too, after all. All this software-injected mitigations
and maskings aren't free.

~~~
kevingadd
The experience of literally every browser vendor does not support your claim
that it is 'trivially cheap'.

Problems worth thinking about:

Sharing jitted code across processes (including runtime-shared things like
standard library APIs) - lots of effort has gone into optimizing this for V8.

Startup time due to unsharable data. Again lots of effort goes into optimizing
this.

Cost of page tables per process. (This is bad on every OS I know of even if
it's cheaper on some OSes).

Cost of setting up process state like page tables (perhaps small, but still
not free)

Cost of context switches. For browsers with aggressive process isolation this
can be _a lot_.

Cost of fetching content from disk cache into per-process in-memory cache.
This used to be very significant in Chrome, they did something recent to
optimize it. We're talking 10-40 ms per request from context switches and RPC.

Most importantly the risk of having processes OOM killed is significant and
goes up the more processes you have. This is especially bad on Android and iOS
but can be an issue on Linux too.

ASLR and other security mitigations also mean you're touching some pages to do
relocation at startup, aren't you? You're paying that for dozens of processes
now.

~~~
kllrnohj
Those are all costs of doing multi-process at all. Once you've committed to
that (which every browser vendor did long before spectre was a thing), doing
it per site-origin doesn't significantly change things.

As for the actual problems, many of those are very solvable. Startup time, for
example, can be nearly entirely eliminated on OS's with fork() (and those that
don't have a fork need to hurry up and get one) - a trick Android leverages
heavily.

And a round-trip IPC is not 10-40ms, it's more like 20-50us (
[https://chromium.googlesource.com/chromium/src/+/master/mojo...](https://chromium.googlesource.com/chromium/src/+/master/mojo/README.md#What-
are-the-performance-characteristics-of-Mojo) )

> Most importantly the risk of having processes OOM killed is significant and
> goes up the more processes you have. This is especially bad on Android

There's no significant risk here on Android. Bound services will have the same
OOM adj as the binding process.

~~~
kevingadd
Cache round-trips in chrome were historically 10-40 ms, you could see it in
devtools. I have old profiles. You're thinking the optimal cost of a round-
trip, not the actual cost of routing 1mb assets over an IPC pipe

------
0x0
The linked paper contains a quote and a reference to Microsoft Singularity
that really is an interesting thought experiment. Imagine we were all running
next-gen systems designed like Singularity by now, which relies on type safety
and managed code instead of memory protection to provide application level
security. Spectre would have been a lot more devastating then, if we couldn't
have hardware-assisted virtual memory protection separating processes from
each other?

[https://en.wikipedia.org/wiki/Singularity_(operating_system)](https://en.wikipedia.org/wiki/Singularity_\(operating_system\))

~~~
milkey_mouse
Singularity heavily relies on capabilities. What if accessing the current wall
clock time was a zealously guarded capability? I wonder what percentage of
apps could function with no access to (real time) timers at all, or an
extremely granular one?

I can't find a link at the moment, but I recall a paper showing even a very
granular clock will suffice for Spectre exploits, albeit with lower bandwidth.
Also, something else would need to be done about multithreading, as an
application could always just spin up another thread counting as fast as it
can to make a poor man's timer.

~~~
Klathmon
I may be wrong, but isn't there an almost unlimited amount of ways that you
could determine wallclock time?

Any kind of networking access can get it (with enough samples, you can get
some crazy precision over even the most inconsistent networks), and really any
kind of I/O could be abused when combined with another exploits.

And if your permissions system doesn't allow I/O, is there really a lot that
your program can do?

~~~
da_chicken
You don't even need networking. If you can create a temp file, you can
probably get the creation or modified time on the file.

~~~
monocasa
Hell, you can make a passable timer for these purposes as long as you have two
threads. No need to leave your process.

------
eitland
One thing that would reduce the attack surface massively is if we stopped
pretending it is OK for every website under the sun to run any code they want
for as long as they want just because I am reading their webpage.

Yep, you could say I'm talking about "crippling" web pages, but I'd rather
phrase it as "pruning" or "removing the worst abuses".

Those who read carefully might have noticed I didn't say "kill Javascript with
fire" or anything like that, and I think we could get far just by having the
browsers limiting (by default) Javascript run time to 3 seconds: start at 20
seconds this summer and aim for 3 seconds next summer, because who seriously
thinks web pages should need to run scripts for minutes after they have
loaded?

I realize there are a couple of problems with the simplified approach above,
so let me try to defuse the ones I see right away:

\- This will break a number of sites: Yep. But if we really wanted and we got
all browser vendors behind it we it wouldn't take long before all mainstream
sites would be optimizing their js like crazy to make sure it loaded withing
20, then 19 seconds etc. That said: Good luck getting all browser vendors on
board with this. (And, in my defense: I didn't say it would be easy, or even
possible, only that I think it would be a good idea to do.)

\- Some pages need Javascript because they load content using JS: We can reset
the counter to something reasonable for certain types of user input.

\- Some web pages needs Javascript for <reasons>: let them have a popup like
the ones they get for location sharing etc.

~~~
jensvdh
Do you want to go back to doing everything on the server again like the early
2000s?

Because that's what you'll end up with.

~~~
bartread
You'll also end up with (something like) Flash making a comeback.

Nobody's going to accept a non-interactive web, or even one with crippled
interactivity[1]. They only tolerated it in the 90s due to hardware and
bandwidth limitations, not to mention that the web was new technology back
then. That ship has long since sailed.

Even back then, technologies such as Flash arose because people - initially
website owners/creators and then, of course, users - wanted more interactivity
than HTML 3.2 and 4.x, and slow/limited JavaScript, could deliver.

 _[1] With very few exceptions, the GP being one._

~~~
AnIdiotOnTheNet
> You'll also end up with (something like) Flash making a comeback

Something like Flash did make a comeback and it's just called JavaScript now.
Pretty much exactly the same attack surface, but at least now its a hopelessly
complicated "standard"!

~~~
bartread
> Pretty much exactly the same attack surface, but at least now its a
> hopelessly complicated "standard"!

I know, right? I almost miss Flash: it was certainly a lot simpler to work
with. I'm not even sure about the "almost" in that sentence.

------
rmbryan
The original paper is extraordinary:
[https://arxiv.org/pdf/1902.05178.pdf](https://arxiv.org/pdf/1902.05178.pdf)

~~~
mhandley
From their abstract:

 _As a result of our work, we now believe that speculative vulnerabilities on
today’s hardware defeat all language-enforced confidentiality with no known
comprehensive software mitigations, as we have discovered that untrusted code
can construct a universal read gadget to read all memory in the same address
space through side-channels. In the face of this reality, we have shifted the
security model of the Chrome web browser and V8 to process isolation._

Processes are pretty heavyweight as a way to perform this sort of isolation. I
can't help thinking that something like sthreads and tagged memory from Andrea
Bittau's wedge system would be great OS primitives to have right now.

[http://www0.cs.ucl.ac.uk/staff/M.Handley/papers/wedge.pdf](http://www0.cs.ucl.ac.uk/staff/M.Handley/papers/wedge.pdf)

RIP Andrea.

~~~
Ono-Sendai
Isn't one possible solution to this problem just not to allow untrusted
programs access to clocks and timer features?

~~~
ufo
You can do these things as a mitigation but it doesn't fully solve the problem
because untrusted programs can try to get timing info from other sources. For
example, incrementing a counter inside an infinite while loop can give you a
good estimate of time, measured in cpu clock cycles .

~~~
ynniv
That might not be possible in a single threaded environment like JavaScript.

~~~
stefan_
It was until they added background workers.

There is a known simple mitigation. Don't JIT random JavaScript, back to
interpretation. Of course that means there is no use for V8, which is why it's
not in this paper.

~~~
Klathmon
V8 has a JIT-free mode now, and it's still pretty damn fast in real world
situations. It looks like in synthetic benchmarks they saw up to 80% decrease
in performance, but in real-world applications they saw as little as a 6%
decrease.

[https://v8.dev/blog/jitless](https://v8.dev/blog/jitless)

But even an interpreted language can still be vulnerable to Spectre attacks.

------
bithavoc
> Thus Chrome’s security model no longer assumes language-enforced
> confidentiality within a renderer process.

So V8 never was and never will be a silver bullet for running JS/WASM without
isolation. I wonder what Edge CDN such as Cloudflare[0] and Flastly[1] are
doing to isolate their functions.

[0][https://blog.cloudflare.com/cloud-computing-without-
containe...](https://blog.cloudflare.com/cloud-computing-without-containers/)

[1][https://www.fastly.com/blog/announcing-lucet-fastly-
native-w...](https://www.fastly.com/blog/announcing-lucet-fastly-native-
webassembly-compiler-runtime)

~~~
0815test
Running them on in-order, speculation-free hardware would be quite sufficient,
and come with additional benefits in power efficiency. The thing about Spectre
or Meltdown is that there's really no case for the sorts of out-of-order cpus
that raise these issues, unless you're _truly_ bound by compute or memory
bandwidth on some single-threaded task - which will never be the case for
typical JS/WASM workloads on the "edge".

~~~
phire
> Running them on in-order, speculation-free hardware would be quite
> sufficient.

In-order isn't a magic bullet against Spectre, they still do spectulative
execution after predicting branches and they can still be vunerable. ARM have
listed at least one of their in-order cores as vunerable.

To be free of all speculation you have to go back to the 486, which didn't
even have branch prediction.

Besides, if you are making custom CPUs there are other options to avoid
Spectre that don't require eliminating all spectulative execution.

------
antientropic
> Like many with a background in programming languages and their
> implementations, the idea that safe languages enforce a proper abstraction
> boundary, not allowing well-typed programs to read arbitrary memory, has
> been a guarantee upon which our mental models have been built.

As an aside, the notion that it's very risky to rely only on the type system
to enforce security boundaries is not new. In 2003, Govindavajhala and Appel
[1] showed that you can break the security of the JVM through memory errors.
Basically, an untrusted attacker fills memory with a specially formatted data
structure such that in case of a random bit flip, with high probability, you
get an integer field and a pointer field aliasing each other, allowing you to
do pointer arithmetic. By contrast, it's extremely unlikely that a random bit
flip allows (say) an unprivileged Unix process to get root access.

[1]
[https://www.cs.princeton.edu/~appel/papers/memerr.pdf](https://www.cs.princeton.edu/~appel/papers/memerr.pdf)

------
willvarfar
If they are going with isolation instead, can we have the high-res timers and
shared buffers back?

~~~
readittwice
aren't they already back?

~~~
markdeloura
Using Chrome 73 I was getting pretty wildly variable results back from
performance.now() a week ago. Was near useless when trying to profile some
game code. Apparently the timing results you get back in devtool perf tools
are reliable, but that's not useful for in-game performance dashes or real-
time profiling.

------
Causality1
Spectre is a great example of what effect public perception has on software
development. After it's disclosure the industry absolutely scrambled to patch
it because mainstream news outlets declared the sky was falling. A year in,
and we have hundreds of thousands of slightly older computers with a 20%
performance drop and even modern machines with a 5-10% performance drop to
address a purely hypothetical threat.

Compare this to the various Intel Management Engine exploits from the past
couple years which received no media attention and thus no industry attention.

------
bogomipz
The article states:

>Extract the hidden state to recover the inaccessible data. For this, the
attacker needs a clock of sufficient precision. (Surprisingly low-resolution
clocks can be sufficient, especially with techniques such as edge
thresholding.)

Might anyone have some good resources or links they could share on this "edge
thresholding" technique?

------
norswap
Small question: how can they know that it's a mispredicted branch that is
being executed (so that they can set the poison appropriately)? If they have
this knowledge, couldn't they simply drop the execution since it's a
misprediction?

------
wyldfire
> we productionized and deployed site isolation for as many platforms as
> possible by May 2018.

Is there a way to determine whether site isolation is available/enabled on my
chrome platform?

------
MichaelMoser123
couldn't Intel add a per thread option to enable/disable speculative
execution? This option could be disabled once a thread is about to execute
just in time compiled code, Javascript would then run slower - but without the
specter of Spectre..

------
eclipseo76
Does anyone know if SELinux can mitigate some of these vulnerabilities?

~~~
monocasa
It does not.

------
omnifischer
offtopic: Kudos to the author for having simple and fast loading page without
any js or complicated CSS. Loads blazing fast. No tracking too.

~~~
mathias
Thanks :) Glad to see people appreciate simplicity (and the performance that
comes with it).

------
supermatt
It is sad that the solution is to cripple the software. I hope that these
workarounds will be relegated to compatibility issues in the future as the
underlying hardware is eventually fixed.

~~~
supermatt
Not sure why i got downvoted for this. Anyone care to enlighten me?

~~~
MiroF
Any solution requires "crippling the software" \- process isolation increases
overhead through kernel context switches

~~~
supermatt
I suppose this is where I realise I don't actually understand the underlying
issue. If it is a software issue, why is there so much blame directed to the
hardware vendors?

~~~
MiroF
It's a hardware issue - ie. it is caused by compromises hardware made to speed
up execution times.

Because we're stuck with the hardware we have, we can make software fixes -
however they are going to require either slowing down or removing certain
features until we get a hardware fix for the issue.

~~~
supermatt
thank you. I read in another comment that this isn't an issue with process
isolation of memory (which I originally thought), its an issue with the
isolation of memory within the process - would you say that is a good
summarisation? i.e. the hardware is working as designed, but the software is
expecting guarantees that the hardware never promised?

~~~
int_19h
Spectre only allows access to the process' own address space, yes. But
Meltdown works across processes, so hardware manufacturers (and specifically
Intel) have definitely dropped the ball there, as well.

~~~
gpderetta
But meltdown is known to be fixable without significant performance costs
(proof being the existing high performance CPUs that are immune to it).

Spectre not so much.

~~~
MiroF
The problem is the same. The fact that we can hide most of the kernel memory
is handy, but it shouldn't be up to the software to do that - user processes
shouldn't be able to access memory that pagefaults. Definitely a dropped ball
by the manufacturer

~~~
gpderetta
Not the same. As you say, a process should not be able to access pages that
are protected by hardware permission bits. That's exactly the issue with
meltdown.

Spectre is different, it allows reading pages that a process would already
have hardware permission to read[1] but actual permission is enforced at the
software level (i.e. software as opposed to hardware bound checking).

[1] It is possible to construct spectre v1 attacks against other processes in
some cases, but are much harder, low bandwidth and I do not think are yet
shown to be practical.

~~~
MiroF
> Not the same. As you say, a process should not be able to access pages that
> are protected by hardware permission bits. That's exactly the issue with
> meltdown.

Okay, but the hardware issue is pretty much exactly the same... the bug in
hardware that enabled spectre is also what enabled meltdown.

The only reason we managed to fix this is by moving most of the kernel task
memory out of the user page table - a software fix for something that the
hardware should have been doing.

~~~
gpderetta
No, it is really a different bug. One is speculation around branches, the
other one is speculation around hardware protection check (which is not
implemented internally as a branch). In fact, while all OoO CPUs are
vulnerable to spectre, not all of them are vulnerable to meltdown because, for
whatever reason, their designers decided not to speculate around hardware
checks (possibly because the check could be implemented efficiently in the
critical path given their L1 cache design).

I'm not an hardware designer, but likely both instances of speculation use the
same snapshot and rollback logic, but that's about it.

------
Ragib_Zaman
People sometimes talk about waiting for a Spectre "fix" at a hardware or
software level, but it seems that the only fix is to lose Speculative
execution entirely (and with it, its performance gains). On my Haswell CPU,
the performance hit was about 5% in various benchmarks, although newer
architectures suffer less. Given that Spectre attacks still appear to be very
difficult to perform in practice, I wonder if we will start to see Speculative
execution at the hardware level brought back as an option for high performance
and closed environment settings.

~~~
lallysingh
I think you can do it by tracking caches pulled in during speculation and
dumping them if speculation failed. Perhaps on a new barrier instruction
that's lighter weight than lfence (as you're just enabling a recording mode
for cache snooping).

Ultimately I don't think many speculative instructions actually pull in cache
lines, so we can either clean up when they do, or stop speculating when a line
would need to be loaded.

~~~
tntn
I don't see how this would really work. As soon as one core pulls in a cache
line, all the other cores know about it, so somehow you would have to roll
back all the coherency messaging as well.

~~~
gpderetta
You can in a many-world interpretation of quantum mechanics. On a branch
speculation, split the universe. Follow one branch in one universe, the other
in another universe. If the CPU realizes that the speculation is wrong,
destroy the universe (this is left as an exercise for the reader). As a bonus
the CPU will have 100% speculation success. Unfortunately I think quantum
mechanics itself might allow for side channels between universes.

------
jnordwick
And still to this date not single spectre attack shown to work under real
world conditions.

This had been the most overt blown security topic I've ever seen. All the POCs
required higher help from the code being attacked: eg, known memory locations,
nothing else running on the system.

There still has not been a single real world exploit developed for Spectre: eg
somebody attack a running server. But yet all this time and effort has gone
into a theoretical toy. It is so incredibly difficult to pull this off, that
is should be one of the lowest priorities. I guess it gets ink because it
pushes the security issues past all the software foul ups and lets people hate
on Intel.

Developers gotta develop I guess.

Edit: down to -3 already for expressing an opinion, and nobody really
responded except for a variation of the precautionary principle.

I wish more people understood that spectre isn't the bogeyman that we need to
give up 5 to 15% of our CPU for (and meltdown was more of a bug and when
easily patched is no worse than Spectre).

Maybe I should put an encryption key in a sandboxed system and play $1000 if
anybody can use Spectre to recover it? Even then it probably would shut
everybody up.

~~~
mxschumacher
> And still to this date not single spectre attack shown to work under real
> world conditions.

I find statements like yours difficult. Can we know that something did not
happen just because nobody talked about it?

A vulnerability as deep and far reaching as Spectre is extremely interesting
to nation-state level hacking groups as a means of warfare, we should not
assume that we know about everything these actors are up to.

~~~
gmueckl
But if you treat well funded actors as essentially omnipotent entities, you
might just as well lie down and give up. The reality is that although we don't
know everything, there cannot be all that much activity, either, or we would
see many more installations of well crafted exploits and rootkits than what
currently gets reported. And I would expect blackhats to go for some reliable
0 day hack with small code size rather than relying on a complex attack that
first needs to read memory locations in a roundabout way to get anywhere.

~~~
mxschumacher
I'm not saying omnipotent, just much less transparent than the above comment
suggests. I'm not sure how many exploits leak out of military cyber offense
teams in China, Israel or the US.

