about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-06-08 20:10:07 +0000
committerbors <bors@rust-lang.org>2020-06-08 20:10:07 +0000
commitfd4b177aabb9749dfb562c48e47379cea81dc277 (patch)
tree9fa5a5888e7b0c05aa9b798a43c471fd4e106a7f
parentbc10b68e798477066d4b1ec4886a3b1cdc4feb7e (diff)
parentea48f2e4da5c6b120c337466e55b307a26c189b2 (diff)
Auto merge of #72655 - jethrogb:sgx-lvi-hardening, r=petrochenkov
Enable LVI hardening for x86_64-fortanix-unknown-sgx

This implements mitigations for the Load Value Injection vulnerability (CVE-2020-0551) for the `x86_64-fortanix-unknown-sgx` target by enabling new LLVM passes. More information about LVI and mitigations may be found at https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection.

This PR unconditionally enables the mitigations for `x86_64-fortanix-unknown-sgx` since there is no available hardware that doesn't require the mitigations. This may be reconsidered in the future.

* [x] This depends on https://github.com/rust-lang/compiler-builtins/pull/359/
-rw-r--r--Cargo.lock4
-rw-r--r--src/bootstrap/cc_detect.rs4
-rw-r--r--src/ci/docker/dist-various-2/Dockerfile45
-rwxr-xr-xsrc/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh12
-rwxr-xr-xsrc/ci/docker/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh14
-rw-r--r--src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs3
-rw-r--r--src/libstd/Cargo.toml2
-rw-r--r--src/libstd/sys/sgx/abi/entry.S20
8 files changed, 74 insertions, 30 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 76665d5a6f7..01510b71681 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -642,9 +642,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.31"
+version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "702af8463c84fd83dd76a307ebd47ab3cc866e847bebd4a1deeb6bcc4a658327"
+checksum = "7bc4ac2c824d2bfc612cba57708198547e9a26943af0632aff033e0693074d5c"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs
index a236edf971f..ab16ca3732c 100644
--- a/src/bootstrap/cc_detect.rs
+++ b/src/bootstrap/cc_detect.rs
@@ -37,7 +37,9 @@ use crate::{Build, GitRepo};
 // try to infer the archiver path from the C compiler path.
 // In the future this logic should be replaced by calling into the `cc` crate.
 fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
-    if let Some(ar) = env::var_os("AR") {
+    if let Some(ar) = env::var_os(format!("AR_{}", target.replace("-", "_"))) {
+        Some(PathBuf::from(ar))
+    } else if let Some(ar) = env::var_os("AR") {
         Some(PathBuf::from(ar))
     } else if target.contains("msvc") {
         None
diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile
index 5864b5ffab2..43f5581f996 100644
--- a/src/ci/docker/dist-various-2/Dockerfile
+++ b/src/ci/docker/dist-various-2/Dockerfile
@@ -28,6 +28,29 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
 RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
 RUN add-apt-repository -y 'deb http://apt.dilos.org/dilos dilos2 main'
 
+ENV \
+    AR_x86_64_fuchsia=x86_64-fuchsia-ar \
+    CC_x86_64_fuchsia=x86_64-fuchsia-clang \
+    CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \
+    AR_aarch64_fuchsia=aarch64-fuchsia-ar \
+    CC_aarch64_fuchsia=aarch64-fuchsia-clang \
+    CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \
+    AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \
+    CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \
+    CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
+    AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \
+    CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
+    CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \
+    CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-7 \
+    CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-7 \
+    AR_x86_64_fortanix_unknown_sgx=ar \
+    CC_x86_64_fortanix_unknown_sgx=x86_64-fortanix-unknown-sgx-clang-11 \
+    CFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
+    CXX_x86_64_fortanix_unknown_sgx=x86_64-fortanix-unknown-sgx-clang++-11 \
+    CXXFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
+    CC=gcc-7 \
+    CXX=g++-7
+
 WORKDIR /build
 COPY scripts/musl.sh /build
 RUN env \
@@ -46,9 +69,11 @@ COPY dist-various-2/build-solaris-toolchain.sh /tmp/
 RUN /tmp/build-solaris-toolchain.sh x86_64  amd64   solaris-i386
 RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc
 COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
+COPY dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh /usr/bin/x86_64-fortanix-unknown-sgx-clang-11
+RUN ln -s /usr/bin/x86_64-fortanix-unknown-sgx-clang-11 /usr/bin/x86_64-fortanix-unknown-sgx-clang++-11
 # We pass the commit id of the port of LLVM's libunwind to the build script.
 # Any update to the commit id here, should cause the container image to be re-built from this point on.
-RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "5125c169b30837208a842f85f7ae44a83533bd0e"
+RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "800f95131fe6acd20b96b6f4723ca3c820f3d379"
 
 COPY dist-various-2/build-wasi-toolchain.sh /tmp/
 RUN /tmp/build-wasi-toolchain.sh
@@ -56,24 +81,6 @@ RUN /tmp/build-wasi-toolchain.sh
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-ENV \
-    AR_x86_64_fuchsia=x86_64-fuchsia-ar \
-    CC_x86_64_fuchsia=x86_64-fuchsia-clang \
-    CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \
-    AR_aarch64_fuchsia=aarch64-fuchsia-ar \
-    CC_aarch64_fuchsia=aarch64-fuchsia-clang \
-    CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \
-    AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \
-    CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \
-    CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
-    AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \
-    CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
-    CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \
-    CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-7 \
-    CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-7 \
-    CC=gcc-7 \
-    CXX=g++-7
-
 ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar
 ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \
 -C link-arg=--sysroot=/usr/local/x86_64-fuchsia \
diff --git a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
index 725ec341b94..4294b1ef93d 100755
--- a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
@@ -13,12 +13,15 @@ url="https://github.com/fortanix/llvm-project/archive/${1}.tar.gz"
 repo_name="llvm-project"
 
 install_prereq() {
+    curl https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
+    add-apt-repository -y 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main'
     apt-get update
     apt-get install -y --no-install-recommends \
             build-essential \
             ca-certificates \
             cmake \
-            git
+            git \
+            clang-11
 }
 
 build_unwind() {
@@ -35,7 +38,14 @@ build_unwind() {
     # Build libunwind
     mkdir -p build
     cd build
+    target_CC="CC_${target//-/_}"
+    target_CXX="CXX_${target//-/_}"
+    target_CFLAGS="CFLAGS_${target//-/_}"
+    target_CXXFLAGS="CXXFLAGS_${target//-/_}"
     cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" \
+        -DCMAKE_C_COMPILER="${!target_CC}" -DCMAKE_CXX_COMPILER="${!target_CXX}" \
+        -DCMAKE_C_FLAGS="${!target_CFLAGS}" -DCMAKE_CXX_FLAGS="${!target_CXXFLAGS}" \
+        -DCMAKE_C_COMPILER_TARGET=$target -DCMAKE_CXX_COMPILER_TARGET=$target \
         -DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_WERROR=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 \
         -DLLVM_PATH=../../llvm/ ../
     make unwind_static
diff --git a/src/ci/docker/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh b/src/ci/docker/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh
new file mode 100755
index 00000000000..c4ff44c37b1
--- /dev/null
+++ b/src/ci/docker/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+args=("$@")
+
+for i in "${!args[@]}"; do
+    # x86_64-fortanix-unknown-sgx doesn't have a C sysroot for things like
+    # stdint.h and the C++ STL. Unlike GCC, clang will not use the host's
+    # sysroot instead. Force it.
+    if [ "${args[$i]}" = "--target=x86_64-fortanix-unknown-sgx" ]; then
+        args[$i]="--target=x86_64-unknown-linux-gnu"
+    fi
+done
+
+exec "${0/x86_64-fortanix-unknown-sgx-clang/clang}" "${args[@]}"
diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
index 475a33af29c..81974769caf 100644
--- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
@@ -61,7 +61,8 @@ pub fn target() -> Result<Target, String> {
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Unwind,
         cpu: "x86-64".into(),
-        features: "+rdrnd,+rdseed".into(),
+        features: "+rdrnd,+rdseed,+lvi-cfi,+lvi-load-hardening".into(),
+        llvm_args: vec!["--x86-experimental-lvi-inline-asm-hardening".into()],
         position_independent_executables: true,
         pre_link_args: iter::once((
             LinkerFlavor::Lld(LldFlavor::Ld),
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 39d786e5997..6af1cbb34b6 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -20,7 +20,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
 core = { path = "../libcore" }
 libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.31" }
+compiler_builtins = { version = "0.1.32" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-dep-of-std'] }
diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S
index 1f06c9da3a9..2badfc973c9 100644
--- a/src/libstd/sys/sgx/abi/entry.S
+++ b/src/libstd/sys/sgx/abi/entry.S
@@ -324,7 +324,9 @@ usercall:
 /*  return */
     mov %rsi,%rax /*  RAX = return value */
     /* NOP: mov %rdx,%rdx */ /*  RDX = return value */
-    ret
+    pop %r11
+    lfence
+    jmp *%r11
 
 /*
 The following functions need to be defined externally:
@@ -343,20 +345,28 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64
 .global get_tcs_addr
 get_tcs_addr:
     mov %gs:tcsls_tcs_addr,%rax
-    ret
+    pop %r11
+    lfence
+    jmp *%r11
 
 .global get_tls_ptr
 get_tls_ptr:
     mov %gs:tcsls_tls_ptr,%rax
-    ret
+    pop %r11
+    lfence
+    jmp *%r11
 
 .global set_tls_ptr
 set_tls_ptr:
     mov %rdi,%gs:tcsls_tls_ptr
-    ret
+    pop %r11
+    lfence
+    jmp *%r11
 
 .global take_debug_panic_buf_ptr
 take_debug_panic_buf_ptr:
     xor %rax,%rax
     xchg %gs:tcsls_debug_panic_buf_ptr,%rax
-    ret
+    pop %r11
+    lfence
+    jmp *%r11