[PATCH] D41760: Introduce __builtin_load_no_speculate

Kristof Beyls via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 5 03:02:26 PST 2018


kristof.beyls created this revision.
kristof.beyls added a reviewer: olista01.
Herald added subscribers: aheejin, javed.absar, dschuff, jfb, aemerson.

Recently, Google Project Zero disclosed several classes of attack
against speculative execution. One of these, known as variant-1
(CVE-2017-5753), allows explicit bounds checks to be bypassed under
speculation, providing an arbitrary read gadget. Further details can
be found on the GPZ blog [1].

This patch adds a new builtin function that provides a mechanism for
limiting speculation by a CPU after a bounds-checked memory access.
This patch provides the clang-side of the needed functionality; there is
also an llvm-side patch this patch is dependent on.
We've tried to design this in such a way that it can be used for any
target where this might be necessary.  The patch provides a generic
implementation of the builtin, with most of the target-specific
support in the LLVM counter part to this clang patch.

The signature of the new, polymorphic, builtin is:

T __builtin_load_no_speculate(const volatile T *ptr,

  const volatile void *lower,
  const volatile void *upper,
  T failval,
  const volatile void *cmpptr)

T can be any integral type (signed or unsigned char, int, short, long,
etc) or any pointer type.

The builtin implements the following logical behaviour:

inline T __builtin_load_no_speculate(const volatile T *ptr,

                                     const volatile void *lower,
                                     const volatile void *upper, T failval,
                                     const volatile void *cmpptr) {
  T result;
  if (cmpptr >= lower && cmpptr < upper)
    result = *ptr;
  else
    result = failval;
  return result;

}

In addition, the builtin ensures that future speculation using *ptr may
only continue iff cmpptr lies within the bounds specified.

To make the builtin easier to use, the final two arguments can both be
omitted: failval will default to 0 in this case and if cmpptr is omitted
ptr will be used for expansions of the range check.  In addition, either
lower or upper (but not both) may be a literal NULL and the expansion
will then ignore that boundary condition when expanding.

This also introduces the predefined pre-processor macro
__HAVE_LOAD_NO_SPECULATE, that allows users to check if their version of
the compiler supports this intrinsic.

The builtin is defined for all architectures, even if they do not
provide a mechanism for inhibiting speculation.  If they do not have
such support the compiler will emit a warning and simply implement the
architectural behavior of the builtin.

This patch can be used with the header file that Arm recently
published here: https://github.com/ARM-software/speculation-barrier.

Kernel patches are also being developed, eg:
https://lkml.org/lkml/2018/1/3/754.  The intent is that eventually
code like this will be able to use support directly from the compiler
in a portable manner.

Similar patches are also being developed for GCC and have been posted to
their development list, see
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00205.html

[1] More information on the topic can be found here:
https://googleprojectzero.blogspot.co.uk/2018/01/reading-privileged-memory-with-side.html
Arm specific information can be found here:
https://www.arm.com/security-update


https://reviews.llvm.org/D41760

Files:
  include/clang/Basic/Builtins.def
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/TargetInfo.h
  include/clang/Sema/Sema.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/Basic/Targets/ARM.cpp
  lib/Basic/Targets/ARM.h
  lib/CodeGen/CGBuiltin.cpp
  lib/Frontend/InitPreprocessor.cpp
  lib/Sema/SemaChecking.cpp
  test/CodeGen/builtin-load-no-speculate.c
  test/Preprocessor/init.c
  test/Sema/builtin-load-no-speculate-c.c
  test/Sema/builtin-load-no-speculate-cxx.cpp
  test/Sema/builtin-load-no-speculate-target-not-supported.c

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41760.128726.patch
Type: text/x-patch
Size: 40811 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180105/ae5f1a63/attachment-0001.bin>


More information about the cfe-commits mailing list