diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 9e4d6d0023dc9..1e233cb389187 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -625,7 +625,14 @@ impl Step for TestHelpers { if builder.config.dry_run { return; } - let target = self.target; + // The x86_64-fortanix-unknown-sgx target doesn't have a working C + // toolchain. However, some x86_64 ELF objects can be linked + // without issues. Use this hack to compile the test helpers. + let target = if self.target == "x86_64-fortanix-unknown-sgx" { + TargetSelection::from_user("x86_64-unknown-linux-gnu") + } else { + self.target + }; let dst = builder.test_helpers_out(target); let src = builder.src.join("src/test/auxiliary/rust_test_helpers.c"); if up_to_date(&src, &dst.join("librust_test_helpers.a")) { @@ -649,7 +656,6 @@ impl Step for TestHelpers { } cfg.compiler(builder.cc(target)); } - cfg.cargo_metadata(false) .out_dir(&dst) .target(&target.triple) diff --git a/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs new file mode 100644 index 0000000000000..79d82cf70d381 --- /dev/null +++ b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs @@ -0,0 +1,17 @@ +// Test LVI load hardening on SGX enclave code + +// assembly-output: emit-asm +// compile-flags: --crate-type staticlib +// only-x86_64-fortanix-unknown-sgx + +#[no_mangle] +pub extern fn plus_one(r: &mut u64) { + *r = *r + 1; +} + +// CHECK: plus_one +// CHECK: lfence +// CHECK-NEXT: addq +// CHECK: popq [[REGISTER:%[a-z]+]] +// CHECK-NEXT: lfence +// CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs new file mode 100644 index 0000000000000..a21ef6b75894e --- /dev/null +++ b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs @@ -0,0 +1,12 @@ +// Test LVI ret hardening on generic rust code + +// assembly-output: emit-asm +// compile-flags: --crate-type staticlib +// only-x86_64-fortanix-unknown-sgx + +#[no_mangle] +pub extern fn myret() {} +// CHECK: myret: +// CHECK: popq [[REGISTER:%[a-z]+]] +// CHECK-NEXT: lfence +// CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs new file mode 100644 index 0000000000000..7e440169edbb1 --- /dev/null +++ b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs @@ -0,0 +1,41 @@ +// Test LVI load hardening on SGX inline assembly code + +// assembly-output: emit-asm +// compile-flags: --crate-type staticlib +// only-x86_64-fortanix-unknown-sgx + +#![feature(asm)] + +#[no_mangle] +pub extern fn get(ptr: *const u64) -> u64 { + let value : u64; + unsafe { + asm!(".start_inline_asm:", + "mov {}, [{}]", + ".end_inline_asm:", + out(reg) value, + in(reg) ptr); + } + value +} + +// CHECK: get +// CHECK: .start_inline_asm +// CHECK-NEXT: movq +// CHECK-NEXT: lfence +// CHECK-NEXT: .end_inline_asm + +#[no_mangle] +pub extern fn myret() { + unsafe { + asm!(".start_myret_inline_asm: + ret + .end_myret_inline_asm:"); + } +} + +// CHECK: myret +// CHECK: .start_myret_inline_asm +// CHECK-NEXT: shlq $0, (%rsp) +// CHECK-NEXT: lfence +// CHECK-NEXT: retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile new file mode 100644 index 0000000000000..6a04d34391035 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile @@ -0,0 +1,23 @@ +-include ../../run-make-fulldeps/tools.mk + +#only-x86_64-fortanix-unknown-sgx + +# For cargo setting +export RUSTC := $(RUSTC_ORIGINAL) +export LD_LIBRARY_PATH := $(HOST_RPATH_DIR) +# We need to be outside of 'src' dir in order to run cargo +export WORK_DIR := $(TMPDIR) +export TEST_DIR := $(shell pwd) + +## clean up unused env variables which might cause harm. +unexport RUSTC_LINKER +unexport RUSTC_BOOTSTRAP +unexport RUST_BUILD_STAGE +unexport RUST_TEST_THREADS +unexport RUST_TEST_TMPDIR +unexport AR +unexport CC +unexport CXX + +all: + bash script.sh diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks new file mode 100644 index 0000000000000..e839c200bbb96 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks @@ -0,0 +1,8 @@ +CHECK: cc_plus_one_asm +CHECK-NEXT: movl +CHECK-NEXT: lfence +CHECK-NEXT: inc +CHECK-NEXT: notq (%rsp) +CHECK-NEXT: notq (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c.checks new file mode 100644 index 0000000000000..b93b33afb3fc4 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c.checks @@ -0,0 +1,6 @@ +CHECK: cc_plus_one_c +CHECK: lfence +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks new file mode 100644 index 0000000000000..d1fae3d495fb1 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks @@ -0,0 +1,15 @@ +CHECK: cc_plus_one_c_asm +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK-NEXT: incl +CHECK-NEXT: jmp +CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx.checks new file mode 100644 index 0000000000000..f96f152c02fcc --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx.checks @@ -0,0 +1,6 @@ +CHECK: cc_plus_one_cxx +CHECK: lfence +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks new file mode 100644 index 0000000000000..e704bf4172434 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks @@ -0,0 +1,16 @@ +CHECK: cc_plus_one_cxx_asm +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: movl +CHECK: lfence +CHECK: lfence +CHECK-NEXT: incl +CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} +CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks new file mode 100644 index 0000000000000..78b18ccbfcb31 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks @@ -0,0 +1,7 @@ +CHECK: cmake_plus_one_asm +CHECK-NEXT: movl +CHECK-NEXT: lfence +CHECK-NEXT: incl +CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c.checks new file mode 100644 index 0000000000000..f551356b2ff81 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c.checks @@ -0,0 +1,6 @@ +CHECK: cmake_plus_one_c +CHECK: lfence +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks new file mode 100644 index 0000000000000..87c806f137a94 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks @@ -0,0 +1,16 @@ +CHECK: cmake_plus_one_c_asm +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: movl +CHECK: lfence +CHECK-NEXT: incl +CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} +CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_global_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_global_asm.checks new file mode 100644 index 0000000000000..4b66cc5bc83b5 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_global_asm.checks @@ -0,0 +1,2 @@ +CHECK: cmake_plus_one_c_global_asm +CHECK: lfence diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx.checks new file mode 100644 index 0000000000000..0f403e0203c12 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx.checks @@ -0,0 +1,6 @@ +CHECK: cmake_plus_one_cxx +CHECK: lfence +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks new file mode 100644 index 0000000000000..9cac8711ea84b --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks @@ -0,0 +1,16 @@ +CHECK: cmake_plus_one_cxx_asm +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: movl +CHECK: lfence +CHECK-NEXT: incl +CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} +CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq +CHECK: popq +CHECK-NEXT: popq [[REGISTER:%[a-z]+]] +CHECK-NEXT: lfence +CHECK-NEXT: jmpq *[[REGISTER]] diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_global_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_global_asm.checks new file mode 100644 index 0000000000000..d4a3d4479014c --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_global_asm.checks @@ -0,0 +1,2 @@ +CHECK: cmake_plus_one_cxx_global_asm +CHECK: lfence diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/Cargo.toml b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/Cargo.toml new file mode 100644 index 0000000000000..89490686584d5 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "enclave" +version = "0.1.0" +authors = ["Raoul Strackx "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[build-dependencies] +cc = "1.0" +cmake = "0.1" diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs new file mode 100644 index 0000000000000..3a7aa1be868c9 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs @@ -0,0 +1,30 @@ +fn main() { + cc::Build::new() + .file("foo.c") + .compile("foo_c"); + + cc::Build::new() + .file("foo_asm.s") + .compile("foo_asm"); + + cc::Build::new() + .cpp(true) + .cpp_set_stdlib(None) + .file("foo_cxx.cpp") + .compile("foo_cxx"); + + // When the cmake crate detects the clang compiler, it passes the + // "--target" argument to the linker which subsequently fails. The + // `CMAKE_C_COMPILER_FORCED` option makes sure that `cmake` does not + // tries to test the compiler. From version 3.6 the option + // `CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY` can be used + // https://cmake.org/cmake/help/v3.5/module/CMakeForceCompiler.html + let dst = cmake::Config::new("libcmake_foo") + .build_target("cmake_foo") + .define("CMAKE_C_COMPILER_FORCED", "1") + .define("CMAKE_CXX_COMPILER_FORCED", "1") + .define("CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY", "1") + .build(); + println!("cargo:rustc-link-search=native={}/build/", dst.display()); + println!("cargo:rustc-link-lib=static=cmake_foo"); +} diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo.c b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo.c new file mode 100644 index 0000000000000..dd76d4f303a95 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo.c @@ -0,0 +1,18 @@ +int cc_plus_one_c(int *arg) { + return *arg + 1; +} + +int cc_plus_one_c_asm(int *arg) { + int value = 0; + + asm volatile ( " movl (%1), %0\n" + " inc %0\n" + " jmp 1f\n" + " retq\n" // never executed, but a shortcut to determine how + // the assembler deals with `ret` instructions + "1:\n" + : "=r"(value) + : "r"(arg) ); + + return value; +} diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_asm.s b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_asm.s new file mode 100644 index 0000000000000..6d56214e87ed9 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_asm.s @@ -0,0 +1,7 @@ + .text + .global cc_plus_one_asm + .type cc_plus_one_asm, @function +cc_plus_one_asm: + movl (%rdi), %eax + inc %eax + retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_cxx.cpp b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_cxx.cpp new file mode 100644 index 0000000000000..ac6f64ac413d0 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/foo_cxx.cpp @@ -0,0 +1,21 @@ +extern "C" int cc_plus_one_cxx(int *arg); +extern "C" int cc_plus_one_cxx_asm(int *arg); + +int cc_plus_one_cxx(int *arg) { + return *arg + 1; +} + +int cc_plus_one_cxx_asm(int *arg) { + int value = 0; + + asm volatile ( " movl (%1), %0\n" + " inc %0\n" + " jmp 1f\n" + " retq\n" // never executed, but a shortcut to determine how + // the assembler deals with `ret` instructions + "1:\n" + : "=r"(value) + : "r"(arg) ); + + return value; +} diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/CMakeLists.txt b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/CMakeLists.txt new file mode 100644 index 0000000000000..27cdf2ecf826d --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/CMakeLists.txt @@ -0,0 +1,33 @@ +enable_language(C CXX ASM) + +set(C_SOURCES + src/foo.c + ) + +set_source_files_properties(${C_SOURCES} + PROPERTIES + LANGUAGE C) + +set(CXX_SOURCES + src/foo_cxx.cpp + ) + +set_source_files_properties(${CXX_SOURCES} + PROPERTIES + LANGUAGE CXX) + +set(ASM_SOURCES + src/foo_asm.s + ) + +set_source_files_properties(${ASM_SOURCES} + PROPERTIES + LANGUAGE ASM) + +set(SOURCES + ${C_SOURCES} + ${CXX_SOURCES} + ${ASM_SOURCES}) + +add_library(cmake_foo STATIC + ${SOURCES}) diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo.c b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo.c new file mode 100644 index 0000000000000..c3b731a2d5096 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo.c @@ -0,0 +1,26 @@ +int cmake_plus_one_c(int *arg) { + return *arg + 1; +} + +int cmake_plus_one_c_asm(int *arg) { + int value = 0; + + asm volatile ( " movl (%1), %0\n" + " inc %0\n" + " jmp 1f\n" + " retq\n" // never executed, but a shortcut to determine how + // the assembler deals with `ret` instructions + "1:\n" + : "=r"(value) + : "r"(arg) ); + + return value; +} + +asm(".text\n" +" .global cmake_plus_one_c_global_asm\n" +" .type cmake_plus_one_c_global_asm, @function\n" +"cmake_plus_one_c_global_asm:\n" +" movl (%rdi), %eax\n" +" inc %eax\n" +" retq\n" ); diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_asm.s b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_asm.s new file mode 100644 index 0000000000000..64b6b430eeaa1 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_asm.s @@ -0,0 +1,7 @@ + .text + .global cmake_plus_one_asm + .type cmake_plus_one_asm, @function +cmake_plus_one_asm: + movl (%rdi), %eax + inc %eax + retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_cxx.cpp b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_cxx.cpp new file mode 100644 index 0000000000000..824e2afebcc78 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/libcmake_foo/src/foo_cxx.cpp @@ -0,0 +1,29 @@ +extern "C" int cmake_plus_one_cxx(int *arg); +extern "C" int cmake_plus_one_cxx_asm(int *arg); + +int cmake_plus_one_cxx(int *arg) { + return *arg + 1; +} + +int cmake_plus_one_cxx_asm(int *arg) { + int value = 0; + + asm volatile ( " movl (%1), %0\n" + " inc %0\n" + " jmp 1f\n" + " retq\n" // never executed, but a shortcut to determine how + // the assembler deals with `ret` instructions + "1:\n" + : "=r"(value) + : "r"(arg) ); + + return value; +} + +asm(".text\n" +" .global cmake_plus_one_cxx_global_asm\n" +" .type cmake_plus_one_cxx_global_asm, @function\n" +"cmake_plus_one_cxx_global_asm:\n" +" movl (%rdi), %eax\n" +" inc %eax\n" +" retq\n" ); diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs new file mode 100644 index 0000000000000..8e91a8d842c62 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs @@ -0,0 +1,48 @@ +#![feature(global_asm)] + +global_asm!( r#" + .text + .global rust_plus_one_global_asm + .type rust_plus_one_global_asm, @function +rust_plus_one_global_asm: + movl (%rdi), %eax + inc %eax + retq +"# ); + +extern { + fn cc_plus_one_c(arg : &u32) -> u32; + fn cc_plus_one_c_asm(arg : &u32) -> u32; + fn cc_plus_one_cxx(arg : &u32) -> u32; + fn cc_plus_one_cxx_asm(arg : &u32) -> u32; + fn cc_plus_one_asm(arg : &u32) -> u32; + fn cmake_plus_one_c(arg : &u32) -> u32; + fn cmake_plus_one_c_asm(arg : &u32) -> u32; + fn cmake_plus_one_cxx(arg : &u32) -> u32; + fn cmake_plus_one_cxx_asm(arg : &u32) -> u32; + fn cmake_plus_one_c_global_asm(arg : &u32) -> u32; + fn cmake_plus_one_cxx_global_asm(arg : &u32) -> u32; + fn cmake_plus_one_asm(arg : &u32) -> u32; + fn rust_plus_one_global_asm(arg : &u32) -> u32; +} + +fn main() { + let value : u32 = 41; + let question = "Answer to the Ultimate Question of Life, the Universe, and Everything:"; + + unsafe{ + println!("{}: {}!", question,rust_plus_one_global_asm(&value)); + println!("{}: {}!", question,cc_plus_one_c(&value)); + println!("{}: {}!", question,cc_plus_one_c_asm(&value)); + println!("{}: {}!", question,cc_plus_one_cxx(&value)); + println!("{}: {}!", question,cc_plus_one_cxx_asm(&value)); + println!("{}: {}!", question,cc_plus_one_asm(&value)); + println!("{}: {}!", question,cmake_plus_one_c(&value)); + println!("{}: {}!", question,cmake_plus_one_c_asm(&value)); + println!("{}: {}!", question,cmake_plus_one_cxx(&value)); + println!("{}: {}!", question,cmake_plus_one_cxx_asm(&value)); + println!("{}: {}!", question,cmake_plus_one_c_global_asm(&value)); + println!("{}: {}!", question,cmake_plus_one_cxx_global_asm(&value)); + println!("{}: {}!", question,cmake_plus_one_asm(&value)); + } +} diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/jumpto.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/jumpto.checks new file mode 100644 index 0000000000000..15211e3ade795 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/jumpto.checks @@ -0,0 +1,8 @@ +CHECK: libunwind::Registers_x86_64::jumpto +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/print.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/print.checks new file mode 100644 index 0000000000000..0fe88141b2473 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/print.checks @@ -0,0 +1,7 @@ +CHECK: print +CHECK: lfence +CHECK: lfence +CHECK: lfence +CHECK: popq +CHECK: callq 0x{{[[:xdigit:]]*}} <_Unwind_Resume> +CHECK-NEXT: ud2 diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/rust_plus_one_global_asm.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/rust_plus_one_global_asm.checks new file mode 100644 index 0000000000000..fe6777537fb80 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/rust_plus_one_global_asm.checks @@ -0,0 +1,2 @@ +CHECK: rust_plus_one_global_asm +CHECK: lfence diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh new file mode 100644 index 0000000000000..ec93c98016078 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh @@ -0,0 +1,57 @@ +set -exuo pipefail + +function build { + CRATE=enclave + + mkdir -p $WORK_DIR + pushd $WORK_DIR + rm -rf $CRATE + cp -a $TEST_DIR/enclave . + pushd $CRATE + echo ${WORK_DIR} + # HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features. + # These come from the top-level Rust workspace, that this crate is not a + # member of, but Cargo tries to load the workspace `Cargo.toml` anyway. + env RUSTC_BOOTSTRAP=1 + cargo -v run --target $TARGET + popd + popd +} + +function check { + local func=$1 + local checks="${TEST_DIR}/$2" + local asm=$(mktemp) + local objdump="${BUILD_DIR}/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-objdump" + local filecheck="${BUILD_DIR}/x86_64-unknown-linux-gnu/llvm/build/bin/FileCheck" + + ${objdump} --disassemble-symbols=${func} --demangle \ + ${WORK_DIR}/enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave > ${asm} + ${filecheck} --input-file ${asm} ${checks} +} + +build + +check unw_getcontext unw_getcontext.checks +check "libunwind::Registers_x86_64::jumpto()" jumpto.checks +check "std::io::stdio::_print::h87f0c238421c45bc" print.checks +check rust_plus_one_global_asm rust_plus_one_global_asm.checks \ + || echo "warning: module level assembly currently not hardened" + +check cc_plus_one_c cc_plus_one_c.checks +check cc_plus_one_c_asm cc_plus_one_c_asm.checks +check cc_plus_one_cxx cc_plus_one_cxx.checks +check cc_plus_one_cxx_asm cc_plus_one_cxx_asm.checks +check cc_plus_one_asm cc_plus_one_asm.checks \ + || echo "warning: the cc crate forwards assembly files to the CC compiler." \ + "Clang uses its own intergrated assembler, which does not include the LVI passes." + +check cmake_plus_one_c cmake_plus_one_c.checks +check cmake_plus_one_c_asm cmake_plus_one_c_asm.checks +check cmake_plus_one_c_global_asm cmake_plus_one_c_global_asm.checks \ + || echo "warning: module level assembly currently not hardened" +check cmake_plus_one_cxx cmake_plus_one_cxx.checks +check cmake_plus_one_cxx_asm cmake_plus_one_cxx_asm.checks +check cmake_plus_one_cxx_global_asm cmake_plus_one_cxx_global_asm.checks \ + || echo "warning: module level assembly currently not hardened" +check cmake_plus_one_asm cmake_plus_one_asm.checks diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks new file mode 100644 index 0000000000000..4b7615b115dc4 --- /dev/null +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks @@ -0,0 +1,6 @@ +CHECK: unw_getcontext +CHECK: lfence +CHECK: lfence +CHECK: shlq $0, (%rsp) +CHECK-NEXT: lfence +CHECK-NEXT: retq