-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mitigating Spectre attacks #1032
Comments
Yes, I expect we will need mitigations for all variants of Spectre. All of these attacks depend on a high-resolution timer being available to malicious code, so a first-level mitigation is to make sure that the available timer resolution is low enough to make the possible exfiltration bandwidth impractical. Beyond that, I expect the following areas to be affected in Cretonne: Heap bounds checkingHeaps that have 4 GB of guard pages should not be affected, but heap styles that use less virtual address space will generate the kind of bounds checking code that can be exploited to read the full 4 GB of address space following the heap base. We can implement different styles of mitigation:
Jump table bounds checkingCretonne doesn't generate jump tables yet, but it is expected to do so in the future to get good performance for The bounds check on a jump table load can be exploited in much the same way as a heap bounds check. The speculatively executed indirect branch would go to an address that was loaded from outside the jump table. This could potentially be a "speculative gadget" that could be used to leak data. To mitigate this, we can make sure that jump table sizes are a power of two and use index masking to prevent speculative loads from accessing memory outside the jump table. Independent from that, we may also have to use a "retpoline" instead of an indirect branch to avoid indirect branch predictor aliasing. The retpoline alone does not prevent the bounds check exploit. Table call bounds checkingWebAssembly indirect calls use a table of function pointers and trap if you attempt to call a function index outside the table. This bounds check can be exploited the same way as a jump table bounds check. And we need to use retpolines for the indirect call too. |
Thanks for the speedy response Jakob!
Agreed -- FWIW, in our discussions we have defined these requirements for the disclosed flush+reload / evict+time attacks on speculative execution (much detail omitted for brevity):
The idea is that if you can holistically prevent any one of these steps in your design, you break the attacks. In terms of forward-looking architectures we might build cretonne into it is difficult to provide assurance that any one of these will not be possible as systems evolve, so in addition to addressing immediate vulnerabilities we are looking at fixes/mitigations in each step.
Great -- this matches our analysis as well. For programs / linear memories without guard pages, I assume going the lfence route would be far too expensive, but we haven't performed tests along these lines.
Using a mask here to mitigate Spectre variant bytecodealliance/cranelift#1 attacks in cases where makes sense. As I understand cretonne, I think retpoline will be necessary to mitigate Spectre variant bytecodealliance/cranelift#2 attacks in all cases (as you mentioned in a later comment), including abuse of jump tables.
A mitigation (i.e. index masking) or a fix for Spectre variant bytecodealliance/cranelift#1 should be applied here as well then, correct? Maybe this was implied -- just want to make sure I understand correctly. Jon |
Re: Heap bounds checking I haven't measured the performance of using If an application embedding Cretonne can ensure that a power-of-two sized area of memory following the heap base does not contain sensitive information, I think masking the index is a better solution. re: Table call bounds checking Yes, table calls would need mitigation for both Spectre variants 1 and 2 — bounds checking and indirect branch predictor aliasing. Since retpolines specifically disable the indirect branch predictor, I expect that the scales are tipped in favor of using branch trees instead of jump tables for more instances of the WebAssembly |
That makes sense to me, thanks Jakob. This GH issue was meant to be an inquiry -- I'll close it for now. If you'd prefer to use it to track this as a work item feel free to re-open. |
Thanks, Jonathan. I'll leave it open to track remaining work. |
Suggested alternate usage scenario: detect only. No idea how to build this (last time I used an assembler was in 1984 !;), but given these vulnerabilities may never be fixed, seems to me some detection-only tools able to identify live on-line sources of infection would be very helpful. Even more important, some means of detecting tainted package/module updates. (And to be clear, I'm talking about tools to be used on completely unprotected systems.) As one who has extra non-critical-use machines running 24x7, I'd gladly invest time fitting some of them out with detection tools, even with at a performance penalty. Not sure what a 'gadget' is, but seems like it might be possible to plant some 'special-gadgets' capable of leaving breadcrumbs.(?) Also wonder if a 'whistleblower' exploit could be concocted, run-solo on a clean system while storing profile data, then, following each upgrade, detect interference by a potential unsub, by comparing profile changes. Thanks to all working this seriously fubar situation. |
Co-Authored-By: bjorn3 <[email protected]>
I'm doing some issue gardening here and I believe we have done most of the above by now: we have conditional move-based mitigations on heap accesses, table accesses, and branch table loads. We don't have any indirect predictor-specific mitigations yet, but we're working on incorporating hardware CFI techniques (see bytecodealliance/rfcs#17). I'll leave it up to our processor-vendor folks whether they think we have sufficient mitigations now, or with the CFI features, to mark this issue "resolved" -- @akirilov-arm, @abrown, @uweigand, others, what do you think? |
Concerning the Arm architecture, Arm has published documentation on the various speculative execution vulnerabilities. Unfortunately the hardware CFI techniques that are discussed by the RFC proposal mentioned above do not really help with speculative execution attacks that target indirect branch predictors - they rely on instructions that raise processor exceptions, which in most implementations does not happen while executing speculatively; that is somewhat similar to the straight-line speculation vulnerability covered by the documentation. As for the attacks that apply to conditional direct branches, e.g. bounds checks, according to Arm's guidance the conditional moves should be followed by the |
Recently I have done a little bit of research on Spectre-V2, and my conclusion is that on AArch64 the only efficient mitigation (so I exclude techniques such as retpolines) is provided by the
where The We also have a similar attack to contend with, Spectre-BHB. The mitigation against it is to execute a small loop that would be located right next to the operation setting |
Hello,
You are probably well aware, but some mainstream compilers are emitting retpolines to help mitigate Spectre variant 2 attacks. Do you have any plans to add a similar capability to the cretonne code generator (and/or do you think it makes sense for cretonne to do this sort of thing)?
Thanks,
Jon
/cc @tyler @pchickey
The text was updated successfully, but these errors were encountered: