Mitigating straight-line speculation vulnerability CVE-2020-13844

Hi,

A new speculative cache side-channel vulnerability has been published at
https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/downloads/straight-line-speculation,
named "straight-line speculation”, CVE-2020-13844.

In this email, I’d like to explain the toolchain mitigation we’ve prepared
to mitigate against this vulnerability for AArch64. For the full details of the
vulnerability, please follow the above link.
The part of the vulnerability that is relevant to the toolchain mitigations
is as follows.
Some processors may speculatively execute the instructions immediately
following what should be a change in control flow, including RET (returns), BR
(indirect jumps) and BLR (indirect function calls). If the speculative
execution path contains a suitable code sequence, often described as a “Spectre
Revelation Gadget”, such straight-line speculation could lead to changes in the
caches and similar structures that are indicative of secrets, making those
secrets vulnerable to revelation through timing analysis.

The gist of the mitigation is that for RET and BR instructions, a speculation
barrier is placed after them that prohibits incorrect speculation. Since these
barriers are never on the correct, architectural execution path, performance
overhead of this is expected to be low.

The gist of the mitigation for the BLR instruction is a bit more complicated,
to make sure that no barrier gets placed on the architectural execution path.
In summary, a
BLR x
instruction gets transformed to
BL __llvm_slsblr_thunk_x
instruction, with __llvm_slsblr_thunk_x a thunk that contains
__llvm_slsblr_thunk_x:
BR x
speculation barrier

Therefore, the BLR instruction gets split into 2; one BL and one BR. This
transformation results in not inserting a speculation barrier on the
architectural execution path.

Please find patches for these mitigations on the below reviews:

  1. https://reviews.llvm.org/D81399: [AArch64] Fix branch, terminator, etc properties for BRA* instructions.
  2. https://reviews.llvm.org/D81400: [AArch64] Introduce AArch64SLSHardeningPass, which implements the hardening of RET and BR instructions.
  3. https://reviews.llvm.org/D81401: [NFC] Refactor ThunkInserter to make it available for all targets.
  4. https://reviews.llvm.org/D81402: [AArch64] Extend AArch64SLSHardeningPass to harden BLR instructions.
  5. https://reviews.llvm.org/D81403: Work around GlobalISel limitation on Indirect Thunks.
  6. https://reviews.llvm.org/D81404: [AArch64] Add clang command line support for -mharden-sls=
  7. https://reviews.llvm.org/D81405: [AArch64] Avoid incompatibility between SLSBLR mitigation and BTI codegen, by only using X16 and X17 registers for BLRs.

There are a few known places where this toolchain mitigation leaves
instructions unmitigated:

  • Some accesses to thread-local variables use a code sequence with a BLR
    instruction. This code sequence is part of the binary interface between
    compiler and linker. If this BLR instruction needs to be mitigated, it’d
    probably be best to do so in the linker. It seems that the code sequence
    for thread-local variable access is unlikely to lead to a Spectre Revalation
    Gadget.
  • PLT stubs are produced by the linker and each contain a BLR instruction.
    It seems that at most only after the last PLT stub a spectre revalation
    gadget might appear.
  • Use of BR, RET and BLR instructions in assembly are not mitigated.
  • Use of BR, RET and BLR instructions in libraries and run-time library
    routines that are not recompiled with this toolchain mitigation are not
    mitigated.

We’re also posting patches with similar functionality to gcc.

I’d like to request comments and feedback on the above patches.

Thanks,

Kristof

Thanks for doing this. Are the patches suitable for backporting to
10.0.1? I was trying to query on Bugzilla but it seems to be broken
at the moment.

The patches do not intersect too much with the rest of the code base, so I would expect them to be relatively easily backportable.
I’m not sure if 10.0.1 is still open for backporting patches.
Tom, do you know?

The full list of commits that would need to be cherry picked is:

https://reviews.llvm.org/rG09d098506bb9e39d3b0284331a039c8e86eec6e3 [AArch64] Fix branch, terminator, etc properties for BRA* instructions.
https://reviews.llvm.org/rG0ee176edc8b4a6f20527e907bfd026b07a27e7ef [AArch64] Introduce AArch64SLSHardeningPass, implementing hardening of RET and…
https://reviews.llvm.org/rG994748770c3565bcd2c25fcdd0ddb17f6cebab31 [NFC] Refactor ThunkInserter to make it available for all targets.
https://reviews.llvm.org/rGc35ed40f4f1bd8afd709c5342b36f33c7c5b0fbd [AArch64] Extend AArch64SLSHardeningPass to harden BLR instructions.
https://reviews.llvm.org/rG503a26d8e4d07ed63f4dc46fa1a56468c2e53b5f Silence GCC 7 warning
https://reviews.llvm.org/rG3f0cc96a9694e499968544ebda6903982eaeb8a4 [AArch64] SLSHardening: compute correct thunk name for X29.
https://reviews.llvm.org/rG832cfc767246442969c0805fd310a5297c3dbede [IndirectThunks] Make generated MF structure as expected by all instruction…
https://reviews.llvm.org/rGf7455da2633d14f1ce76aaa7c73ea682ac51ac37 [IndirectThunks] Tiny comment fix
https://reviews.llvm.org/rGd938ec4509c47d461377527fc2877ae14b91275c [AArch64] Avoid incompatibility between SLSBLR mitigation and BTI codegen.
https://reviews.llvm.org/rGc113b59ef52593818bcd207521fd490ba3deeaea [AArch64] Add clang command line support for -mharden-sls=