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
RIP Andrea.
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.
But even an interpreted language can still be vulnerable to Spectre attacks.
It doesn't matter if your timing source is high noise with lots of jitter, the attacker can repeat the mesurements over and over again and filter everything out.
Even if the attacker can only pull out a few bytes per second, that might be enough to leak something critical like and encryption key or an ASLR offset.
What about a pure functional language, in which a program computes a result that is a function of the input only.
In this case the only timing information usable for side-channel info leakage would be in the input to the program.
I guess the problems in this case become twofold:
* How can we determine we are not leaking any such info in the input to the program?
and
* Is a pure, functional language sufficient to do the stuff we want, or are they too limited, e.g. for use as a browser scripting language.
But spectre is even worse than that as it attacks at the hardware level. If the CPU does any sort of speculative optimization, through things like caches or branch prediction buffers, then it likely can be the target of a spectre attack. You can try to add spectre mitigations to your language's compiler but, as the article discusses, this approach is an uphill battle.
Pure algorithms are a useful thing in programming. However pure algorithms are not useful on their own, you always need something impure to get the output out.
How do you figure? Processes on some OS's, such as Linux, are pretty cheap. So what are you considering heavy? And how do you imagine a "process switching in userspace" type thing to not just have the same weight as real processes? What's the expensive thing you're trying to eliminate?
I'm really thinking that, we don't really need all the features offered by processes. My current understanding is that we just need a different address space. Why can't we, for example, switch from one set of pages to another when we switch from running trusted browser code to running JIT-ed untrusted code? (Leaving of course a small piece of trampoline code mapped, like KPTI.) On a simple level, this could just be calling mprotect() at certain key locations that result in flipping a few bits in the kernel-maintained page tables. With some good design, perhaps the address for untrusted code and data can be so far away from trusted code and data that maybe just one bit flip is needed in a PML4E.