This is the mail archive of the
mailing list for the GCC project.
[PATCH 00/11] (v2) Mitigation against unsafe data speculation (CVE-2017-5753)
- From: Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Earnshaw <Richard dot Earnshaw at arm dot com>, andrew at codesourcery dot com, andrew at sifive dot com, aoliva at redhat dot com, augustine dot sterling at gmail dot com, bernds_cb1 at t-online dot de, chertykov at gmail dot com, cltang at codesourcery dot com, dave dot anglin at bell dot net, davem at redhat dot com, dje dot gcc at gmail dot com, eager at eagercon dot com, ebotcazou at libertysurf dot fr, gnu at amylaar dot uk, green at moxielogic dot com, hepenner at us dot ibm dot com, hp at axis dot com, hp at bitrange dot com, hubicka at ucw dot cz, james dot bowman at ftdichip dot com, jasonwucj at gmail dot com, jimw at sifive dot com, jzhang918 at gmail dot com, kito dot cheng at gmail dot com, krebbel at linux dot ibm dot com, law at redhat dot com, matt at 3am-software dot com, mfortune at gmail dot com, ni1d at arrl dot net, nickc at redhat dot com, olegendo at gcc dot gnu dot org, palmer at sifive dot com, rth at twiddle dot net, sandra at codesourcery dot com, schwab at linux-m68k dot org, sebastien at milkymist dot org, segher at kernel dot crashing dot org, shiva0217 at gmail dot com, tdevries at suse dot de, trevor_smigiel at playstation dot sony dot com, ubizjak at gmail dot com, uweigand at de dot ibm dot com, walt at tilera dot com, wilson at tuliptree dot org
- Date: Fri, 27 Jul 2018 10:37:44 +0100
- Subject: [PATCH 00/11] (v2) Mitigation against unsafe data speculation (CVE-2017-5753)
- References: <1531154299-28349-1-git-send-email-Richard.Earnshaw@arm.com>
Port Maintainers: You need to decide what action is required for your
port to handle speculative execution, even if that action is to use
the trivial no-speculation on this architecture. You must also
consider whether or not a furture implementation of your architecture
might need to deal with this in making that decision.
The patches I posted earlier this year for mitigating against
CVE-2017-5753 (Spectre variant 1) attracted some useful feedback, from
which it became obvious that a rethink was needed. This mail, and the
following patches attempt to address that feedback and present a new
approach to mitigating against this form of attack surface.
There were two major issues with the original approach:
- The speculation bounds were too tightly constrained - essentially
they had to represent and upper and lower bound on a pointer, or a
- The speculation constraints could only cover the immediately preceding
branch, which often did not fit well with the structure of the existing
An additional criticism was that the shape of the intrinsic did not
fit particularly well with systems that used a single speculation
barrier that essentially had to wait until all preceding speculation
had to be resolved.
To address all of the above, these patches adopt a new approach, based
in part on a posting by Chandler Carruth to the LLVM developers list
but which we have extended to deal with inter-function speculation.
The patches divide the problem into two halves.
The first half is some target-specific code to track the speculation
condition through the generated code to provide an internal variable
which can tell us whether or not the CPU's control flow speculation
matches the data flow calculations. The idea is that the internal
variable starts with the value TRUE and if the CPU's control flow
speculation ever causes a jump to the wrong block of code the variable
becomes false until such time as the incorrect control flow
speculation gets unwound.
The second half is that a new intrinsic function is introduced that is
much simpler than we had before. The basic version of the intrinsic
is now simply:
T var = __builtin_speculation_safe_value (T unsafe_var);
Full details of the syntax can be found in the documentation patch, in
patch 1. In summary, when not speculating the intrinsic returns
unsafe_var; when speculating then if it can be shown that the
speculative flow has diverged from the intended control flow then zero
is returned. An optional second argument can be used to return an
alternative value to zero. The builtin may cause execution to pause
until the speculation state is resolved.
There are eleven patches in this set, as follows.
1) Introduces the new intrinsic __builtin_sepculation_safe_value.
2) Adds a basic hard barrier implementation for AArch32 (arm) state.
3) Adds a basic hard barrier implementation for AArch64 state.
4) Adds a new command-line option -mtrack-speculation (currently a no-op).
5) Disables CB[N]Z and TB[N]Z when -mtrack-speculation.
6) Adds the new speculation tracking pass for AArch64
7) Uses the new speculation tracking pass to generate CSDB-based barrier
8) Provides an alternative hook implementation for use on targets that never
9) Provides an trivial example of using that hook in the pdp11 backend.
10) Provides a possible implementation of the hard barrier for x86
11) Updates the PowerPC backend which already had a suitable barrier under
a different name.
I haven't added a speculation-tracking pass for AArch32 at this time.
It is possible to do this, but would require quite a lot of rework for
the arm backend due to the limited number of registers that are
Although patch 6 is AArch64 specific, I'd appreciate a review from
someone more familiar with the branch edge code than myself. There
appear to be a number of tricky issues with more complex edges so I'd
like a second opinion on that code in case I've missed an important
Richard Earnshaw (11):
Arm - add speculation_barrier pattern
AArch64 - add speculation barrier
AArch64 - Add new option -mtrack-speculation
AArch64 - disable CB[N]Z TB[N]Z when tracking speculation
AArch64 - new pass to add conditional-branch speculation tracking
AArch64 - use CSDB based sequences if speculation tracking is enabled
targhooks - provide an alternative hook for targets that never execute
pdp11 - example of a port not needing a speculation barrier
x86 - add speculation_barrier pattern
rs6000 - add speculation_barrier pattern
gcc/builtin-attrs.def | 2 +
gcc/builtin-types.def | 6 +
gcc/builtins.c | 60 ++++
gcc/builtins.def | 22 ++
gcc/c-family/c-common.c | 164 +++++++++
gcc/c-family/c-cppbuiltin.c | 7 +-
gcc/config.gcc | 2 +-
gcc/config/aarch64/aarch64-passes.def | 1 +
gcc/config/aarch64/aarch64-protos.h | 3 +-
gcc/config/aarch64/aarch64-speculation.cc | 494 ++++++++++++++++++++++++++++
gcc/config/aarch64/aarch64.c | 94 +++++-
gcc/config/aarch64/aarch64.md | 141 +++++++-
gcc/config/aarch64/aarch64.opt | 4 +
gcc/config/aarch64/iterators.md | 3 +
gcc/config/aarch64/t-aarch64 | 10 +
gcc/config/arm/arm.md | 21 ++
gcc/config/arm/unspecs.md | 1 +
gcc/config/i386/i386.md | 10 +
gcc/config/pdp11/pdp11.c | 3 +
gcc/config/rs6000/rs6000.c | 2 +-
gcc/config/rs6000/rs6000.md | 2 +-
gcc/doc/cpp.texi | 4 +
gcc/doc/extend.texi | 91 +++++
gcc/doc/invoke.texi | 10 +-
gcc/doc/md.texi | 15 +
gcc/doc/tm.texi | 36 ++
gcc/doc/tm.texi.in | 4 +
gcc/target.def | 40 +++
gcc/targhooks.c | 39 +++
gcc/targhooks.h | 4 +
gcc/testsuite/c-c++-common/spec-barrier-1.c | 38 +++
gcc/testsuite/c-c++-common/spec-barrier-2.c | 17 +
gcc/testsuite/gcc.dg/spec-barrier-3.c | 13 +
33 files changed, 1350 insertions(+), 13 deletions(-)
create mode 100644 gcc/config/aarch64/aarch64-speculation.cc
create mode 100644 gcc/testsuite/c-c++-common/spec-barrier-1.c
create mode 100644 gcc/testsuite/c-c++-common/spec-barrier-2.c
create mode 100644 gcc/testsuite/gcc.dg/spec-barrier-3.c