4

There are a barrage of patches coming out, both at the application and OS levels for the recently disclosed speculative execution attacks against various vulnerabilities in CPUs from AMD, ARM, and Intel.

I don't fully understand the attacks nor am I seeking a full breakdown of them. What I want to know is what each category of patches that are coming out buys me.

For example, if I am on a Windows OS, running Firefox and Chrome, where the OS is patched, but not any of the browsers, what does that buy me? Is speculative execution to read kernel memory via javascript still possible in that case?

Other then the browser vector, and OS, are there any other obvious risks for end users? I've read of patching for various other software, but I'm confused why other (non browser) software is really relevant here.


As a bonus, I've read that Mozilla and Microsoft have temporarily mitigated the attack via browser, by purposely making some the javascript timing mechanisms inaccurate/less-precise. Isn't it theoretically possible to bundle your own time measuring libraries to bypass that?

4

I'll bite...

Firstly let's handle meltdown (Google: P3). As you probably know, your system has multiple privilege levels for code known on Intel/x86 as ring 0 (supervisor code) and ring 3 (user mode), which are the CPL bitfield choices in your segment selectors. Code is either running using one segment selector or the other (the selectors cover the whole address space) and this determines what privilege the code can execute with.

In parallel, there is virtual memory, controlled by page tables in the CR3 register. Paging allows for a virtual address space of a certain size regardless of the actual amount of backing storage (physical memory) and allows operating system developers to do things like write pages to swap (windows: pagefile) to evict them when tasks are using memory, but have not accessed it for some time and physical RAM is in demand. Page tables also have a user bit, which controls whether code can be seen by code executing at cpl 3. If the bit is set, user mode code can see the page, otherwise not.

Now there are two key points to understand. Firstly, on x86 (and many other architectures), hardware level tasking does not exist. A process, then, (linux task, windows process) is entirely a concept in software. This works by allocating each process its own virtual address space and when processes switch, the relevant pages are switched, "plugging in" the new process into the virtual address space and removing the old one (or unmapping it, even if not evicted from physical RAM) temporarily.

The second thing to understand is that this is a relatively expensive processes, so operating system designers came up with a "higher half kernel": in each process' address space, the kernel is mapped into the higher half of memory completely. This brings us an important advantage: if the kernel needs to handle an interrupt, or perform some IO, we can jump into the kernel space via a system call or interrupt handler and we don't need to switch address spaces of the process. If the task doesn't require us to switch address spaces for any other reason (this is slightly different to a context switch, which is the save of register state, which we can still avoid using the higher half design in some cases) this is nice and efficient: the kernel does its work and returns to user mode as fast as possible.

Unfortunately it turns out that speculative execution occurs across privilege levels on Intel CPUs, specifically that code running as CPL 3 can speculatively load pages with a cleared user bit (so, supervisor/ring 0-2 only). Meltdown exploits this by referencing memory from the higher half on a page-by-page basis through instructions that are only executed speculatively. However, the processor pulls those pages into the higher caches, resulting in a cache based timing side channel.

KPTI and equivalent patches in macOS and Windows protect against this by not using a higher half design. Only the bare minimum needed to enter the kernel address space is mapped into every process; the rest of the kernel lives in its own virtual address space like a separate process. This has two main effects:

  • Any entry to the kernel implies a switch of address spaces. This is more expensive than the higher half design, hence the quotes of a 5%-30% slowdown. The reason for the "it depends on your workload" explanations is because it does depend on how many times you need to enter the kernel.
  • However, now, there is only a small amount of kernel space left in the same virtual address space as the process and most of it is an uninteresting interrupt handler. You can leak it, but, it's a smaller target and its location can be randomized as well. There's simply no valid references any more to things like disk encryption keys and so on, as they exist in a separate virtual address space, which requires a switch to the kernel process first.

This is obviously bad news. The same issue issue can occur for some kinds of hypervisor designs. Containers are a kernel construct entirely and thus are affected, just like processes.

Spectre (Google: P1, P2) works similarly, except it allows the attacker to induce a target to perform some kind of speculative execution in its address space and leak that via a side channel. A critical difference from the Spectre paper is:

Spectre attacks only assume that speculatively executed instructions can read from memory that the victim process could access normally, e.g., without triggering a page fault or exception. For example, if a processor prevents speculative execution of instructions in user processes from accessing kernel memory, the attack will still work. [12]. As a result, Spectre is orthogonal to Meltdown [27]

In other words, you cannot use Spectre to read kernel memory from an unprivilged process directly - or any memory in a higher privilege level.

In order to fix these issues there are a number of possible resolutions:

  • XEN XSA-254's FAQ suggests that Intel, AMD etc are preparing microcode updates that will flush branch prediction logic on entry to the hypervisor, to ensure any attempt at poisoning across this boundary is removed.
  • It also mentions (and this applies elsewhere) applying indirect jumps in code, in such a way that speculative execution does not occur. This defence is to effectively defeat the CPU's optimizer and requires that the software in question is recompiled. It is this defence that is being added to GCC, Clang as mentioned in other answers.

Now, to answer the actual questions you asked:

For example, if I am on a Windows OS, running Firefox and Chrome, where the OS is patched, but not any of the browsers, what does that buy me? Is speculative execution to read kernel memory via javascript still possible in that case?

If you have the KPTI patch series or equivalent, the answer is no, you cannot. Or more precisely, you can, but you can only find uninteresting things like kernel code for switching address spaces.

As a bonus, I've read that Mozilla and Microsoft have temporarily mitigated the attack via browser, by purposely making some the javascript timing mechanisms inaccurate/less-precise. Isn't it theoretically possible to bundle your own time measuring libraries to bypass that?

Theoretically, if a method of measurement exists that is accurate to the required degree in browsers already, yes. However, bundling your own measurement essentially requires extending the browser. It isn't as simple as loading some javascript as, underneath, javascript in the browser is using entirely browser-provided APIs. So theoretically, if there is some code path that allows measurement that has not been closed off, yes, otherwise, no.

I would go with no for all practical purposes, as a result.


Summary:

  • KPTI series patches explicitly protect against Meltdown, i.e. full kernel address space reads, on Intel CPUs.
  • Spectre is harder to protect against as this allows for the same speculative execution, but targeting a different victim process across address spaces. KPTI does not fix it. Individual software packages must deploy mitigations. By contrast, Spectre cannot cross the ring 3-ring 0 privilege boundary (but I believe it can across ring 0 - ring 0 (or "-1" the hypervisor) and hence the Xen comments.
  • 1
    Note that eliminating indirect jumps does not completely prevent Spectre attacks. It eliminates the ability for the attacker to freely choose which code gets speculatively run, but if there's a useful direct branch present in the code, they can still attack that. Completely preventing Spectre requires hardware-level mitigation to prevent one process from influencing another process's branch predictions. – Mark Jan 5 '18 at 10:06
  • In other words, you cannot use Spectre to read kernel memory while technically true, on Linux, you can inject code into the kernel (eBPF bytecode) that runs at ring 0. It has verification to ensure it cannot attack the kernel and so what it can do is limited, but it is able to use Spectre to read kernel memory. Of course the solution there is just to disallow unprivileged use of the bpf() syscall. – forest Jan 5 '18 at 10:50
  • @Mark true. I didn't want to get into mitigations for Spectre as I'm not actually sure it's clear what those need to be yet. There are instructions for preventing speculative execution on ARM such as csdb but not every process can use them and completely disabling speculative execution would kill performance. – diagprov Jan 5 '18 at 11:38
  • @forest true, but that's spectre from ring 0-ring 0. I guess I should more correctly say "you cannot use spectre to read kernel memory from an unprivileged process". I'll edit that in. – diagprov Jan 5 '18 at 11:38
2

For example, if I am on a Windows OS, running Firefox and Chrome, where the OS is patched, but not any of the browsers, what does that buy me? Is speculative execution to read kernel memory via JavaScript still possible in that case?

Yes. I guess. In the case you described you would still be vulnerable to Spectre but (probably?) not to Meltdown. I am not sure if Spectre allows for someone to read kernel memory. But it definitely allows to read memory assigned to another user process.

Patches/Fixes for Spectre will take a while to be available. You can read more about it here.

The gist is, from what I gather, that protection against Spectre needs to happen on a per-process/application level - at least for now. Google, LLVM and GCC developers are already working on this front.

Be aware that, according to the Spectre whitepaper, there is still research needed and it may even be possible to protect against Spectre with microcode updates. Source: Page 13, "7 Countermeasures" of the Spectre whitepaper.

Meanwhile:

Chrome has a feature that, according to Google, will take care of this problem until a full fix will be deployed on January 23rd.


Edit

Reason I'm mentioning Spectre is that in the question "JavaScript" is mentioned. I'm only aware of the JavaScript snippet in the Spectre whitepaper which is why I'm guessing that the person asking the question is not aware that there are two distinct security issues present that are both troubling.


Edit 2

I stumbled over a source I had seen but not read before. This adds some more information.

https://googleprojectzero.blogspot.de/2018/01/reading-privileged-memory-with-side.html.


Edit 3

Firefox has been patched to version 57.0.4. This patch includes the reduction in the precision of the JavaScript time function mentioned in the 'Bonus' part of the question.

  • thanks could you answer the bonus ? – n00b Jan 4 '18 at 15:44
  • for the bonus I found this: blog.mozilla.org/security/2018/01/03/… I'm not a web developer but I don't think you can do what you ask because that DLL or whatever would be executed on the server system - where the website resides - and not on the victim's computer. – Steffen Winkler Jan 4 '18 at 15:57
  • 1
    How does Firefox's first party isolation mitigate this bug? I think you're intending to link to a different blog post? – Lie Ryan Jan 4 '18 at 16:04
  • @LieRyan Google wrote for Chrome: Current stable versions of Chrome include an optional feature called Site Isolation which can be enabled to provide mitigation by isolating websites into separate address spaces from my understanding that is the same feature/function as what Firefox offers. The post just illustrates how to enable it. – Steffen Winkler Jan 4 '18 at 16:08
  • sorry I'm wrong. Fixing my answer now. @LieRyan – Steffen Winkler Jan 4 '18 at 16:15
2

The problem lies within the chip itself. To allow for efficient parallelisation, the processor makes assumptions of what's likely to happen so it can run instructions out-of-order. This is a significant gain of time each time the prediction is right.

Fixing this completely means having a hardware and/or microcode update, especially in the case of Spectre which does not seem to be software correctable.

The software patch (KPTI/KAISER) will allow mitigation of the problem (Meltdown only) by some extend by limiting the amount of kernel space mapped into user space. This patch was design to avoid side-channel attack on the kernel address space layout randomization (KASLR), and does inadvertently protects against meltdown to some extend. It is not complete because of the x86 architecture requirements.

Normally, no user-space program should have to be fixed, since this is a hardware problem. The mitigation is possible because these user-space programs relies on system calls implemented by the kernel code, therefore this gives a bit of control over what gets send to the chip, but stays limited to what the hardware requires to function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.