Auto merge of #77008 - fortanix:raoul/lvi-tests, r=Mark-Simulacrum
LVI hardening tests Mitigating the speculative execution LVI attack against SGX enclaves requires compiler changes (i.e., adding lfences). This pull requests adds various tests to check if this happens correctly.
This commit is contained in:
commit
6369a98ebd
|
@ -630,7 +630,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")) {
|
||||
|
@ -654,7 +661,6 @@ impl Step for TestHelpers {
|
|||
}
|
||||
cfg.compiler(builder.cc(target));
|
||||
}
|
||||
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&dst)
|
||||
.target(&target.triple)
|
||||
|
|
|
@ -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]]
|
|
@ -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]]
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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]]
|
|
@ -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]]
|
|
@ -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]]
|
|
@ -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:]]+}} <cc_plus_one_cxx_asm+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]]
|
|
@ -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
|
|
@ -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]]
|
|
@ -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:]]+}} <cmake_plus_one_c_asm+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]]
|
|
@ -0,0 +1,2 @@
|
|||
CHECK: cmake_plus_one_c_global_asm
|
||||
CHECK: lfence
|
|
@ -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]]
|
|
@ -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:]]+}} <cmake_plus_one_cxx_asm+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]]
|
|
@ -0,0 +1,2 @@
|
|||
CHECK: cmake_plus_one_cxx_global_asm
|
||||
CHECK: lfence
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "enclave"
|
||||
version = "0.1.0"
|
||||
authors = ["Raoul Strackx <raoul.strackx@fortanix.com>"]
|
||||
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"
|
|
@ -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");
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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})
|
|
@ -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" );
|
|
@ -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
|
|
@ -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" );
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
CHECK: print
|
||||
CHECK: lfence
|
||||
CHECK: lfence
|
||||
CHECK: lfence
|
||||
CHECK: popq
|
||||
CHECK: callq 0x{{[[:xdigit:]]*}} <_Unwind_Resume>
|
||||
CHECK-NEXT: ud2
|
|
@ -0,0 +1,2 @@
|
|||
CHECK: rust_plus_one_global_asm
|
||||
CHECK: lfence
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
CHECK: unw_getcontext
|
||||
CHECK: lfence
|
||||
CHECK: lfence
|
||||
CHECK: shlq $0, (%rsp)
|
||||
CHECK-NEXT: lfence
|
||||
CHECK-NEXT: retq
|
Loading…
Reference in New Issue