about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-08-02 11:24:23 +0200
committerGitHub <noreply@github.com>2025-08-02 11:24:23 +0200
commitcafd9fb2d3f2b5179308f3c736341fa9cec61867 (patch)
tree166cc7d5bf95456f903e02d6888f8b3e791bd35c
parentce1961bbfcc71818484d340ea4924f28417657e8 (diff)
parent8b90847416d5678d784942b46c05f8c97caef83d (diff)
downloadrust-cafd9fb2d3f2b5179308f3c736341fa9cec61867.tar.gz
rust-cafd9fb2d3f2b5179308f3c736341fa9cec61867.zip
Rollup merge of #144395 - folkertdev:fortanix-run-make-test, r=jieyouxu
update fortanix tests

Firstly, as far as I can tell, no CI job actually runs any of the fortanix tests? Maybe I'm missing the job that runs these tests though?

In any case, the `assembly` tests now use `minicore`, meaning that they will run regardless of the host architecture (specifically, they will run during a standard PR CI build).

The run-make test is actually broken, and I'd propose to make it just `cargo build` rather than `cargo run`. We can have a separate test for actually running the program, if desired.

Also this test is subject to https://github.com/rust-lang/rust/issues/128733, so I'd like to re-evaluate what parts of the C/C++ compilation are actually required or useful.

cc [``@jethrogb](https://github.com/jethrogb)`` [``@raoulstrackx](https://github.com/raoulstrackx)`` [``@aditijannu](https://github.com/aditijannu)``

r? ``@jieyouxu``
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs31
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs14
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs28
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs43
4 files changed, 74 insertions, 42 deletions
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
index f5e2f18e68e..2892ff2882a 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
@@ -1,17 +1,24 @@
-// Test LVI load hardening on SGX enclave code
+// Test LVI load hardening on SGX enclave code, specifically that `ret` is rewritten.
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx -Copt-level=0
+//@ needs-llvm-components: x86
+
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
-pub extern "C" fn plus_one(r: &mut u64) {
-    *r = *r + 1;
+pub extern "C" fn dereference(a: &mut u64) -> u64 {
+    // CHECK-LABEL: dereference
+    // CHECK: lfence
+    // CHECK: mov
+    // CHECK: popq [[REGISTER:%[a-z]+]]
+    // CHECK-NEXT: lfence
+    // CHECK-NEXT: jmpq *[[REGISTER]]
+    *a
 }
-
-// CHECK: plus_one
-// CHECK: lfence
-// CHECK-NEXT: incq
-// CHECK: popq [[REGISTER:%[a-z]+]]
-// CHECK-NEXT: lfence
-// CHECK-NEXT: jmpq *[[REGISTER]]
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
index f16d68fa255..a0cedc3bc2d 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
@@ -1,12 +1,20 @@
 // Test LVI ret hardening on generic rust code
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx
+//@ needs-llvm-components: x86
+
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
 pub extern "C" fn myret() {}
-// CHECK: myret:
+// CHECK-LABEL: myret:
 // CHECK: popq [[REGISTER:%[a-z]+]]
 // CHECK-NEXT: lfence
 // CHECK-NEXT: jmpq *[[REGISTER]]
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
index a729df8e166..215fb4b804a 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
@@ -1,13 +1,22 @@
 // Test LVI load hardening on SGX inline assembly code
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx
+//@ needs-llvm-components: x86
 
-use std::arch::asm;
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
 pub extern "C" fn get(ptr: *const u64) -> u64 {
+    // CHECK-LABEL: get
+    // CHECK: movq
+    // CHECK-NEXT: lfence
     let value: u64;
     unsafe {
         asm!("mov {}, [{}]",
@@ -17,18 +26,13 @@ pub extern "C" fn get(ptr: *const u64) -> u64 {
     value
 }
 
-// CHECK: get
-// CHECK: movq
-// CHECK-NEXT: lfence
-
 #[no_mangle]
 pub extern "C" fn myret() {
+    // CHECK-LABEL: myret
+    // CHECK: shlq $0, (%rsp)
+    // CHECK-NEXT: lfence
+    // CHECK-NEXT: retq
     unsafe {
         asm!("ret");
     }
 }
-
-// CHECK: myret
-// CHECK: shlq $0, (%rsp)
-// CHECK-NEXT: lfence
-// CHECK-NEXT: retq
diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
index e58762aeb6d..89754cdaf90 100644
--- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
+++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
@@ -13,42 +13,56 @@
 
 //@ only-x86_64-fortanix-unknown-sgx
 
-use run_make_support::{cmd, cwd, llvm_filecheck, llvm_objdump, regex, set_current_dir, target};
+use run_make_support::{
+    cargo, cwd, llvm_filecheck, llvm_objdump, regex, run, set_current_dir, target,
+};
 
 fn main() {
-    let main_dir = cwd();
-    set_current_dir("enclave");
-    // 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.
-    cmd("cargo")
-        .env("RUSTC_BOOTSTRAP", "1")
+    cargo()
         .arg("-v")
-        .arg("run")
+        .arg("build")
         .arg("--target")
         .arg(target())
+        .current_dir("enclave")
+        .env("CC_x86_64_fortanix_unknown_sgx", "clang")
+        .env(
+            "CFLAGS_x86_64_fortanix_unknown_sgx",
+            "-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening",
+        )
+        .env("CXX_x86_64_fortanix_unknown_sgx", "clang++")
+        .env(
+            "CXXFLAGS_x86_64_fortanix_unknown_sgx",
+            "-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening",
+        )
         .run();
-    set_current_dir(&main_dir);
-    // Rust has various ways of adding code to a binary:
+
+    // Rust has several ways of including machine code into a binary:
+    //
     // - Rust code
     // - Inline assembly
     // - Global assembly
     // - C/C++ code compiled as part of Rust crates
-    // For those different kinds, we do have very small code examples that should be
-    // mitigated in some way. Mostly we check that ret instructions should no longer be present.
+    //
+    // For each of those, check that the mitigations are applied. Mostly we check
+    // that ret instructions are no longer present.
+
+    // Check that normal rust code has the right mitigations.
     check("unw_getcontext", "unw_getcontext.checks");
     check("__libunwind_Registers_x86_64_jumpto", "jumpto.checks");
 
     check("std::io::stdio::_print::[[:alnum:]]+", "print.with_frame_pointers.checks");
 
+    // Check that rust global assembly has the right mitigations.
     check("rust_plus_one_global_asm", "rust_plus_one_global_asm.checks");
 
+    // Check that C code compiled using the `cc` crate has the right mitigations.
     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");
 
+    // Check that C++ code compiled using the `cc` crate has the right mitigations.
     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");
@@ -71,8 +85,7 @@ fn check(func_re: &str, mut checks: &str) {
         .input("enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave")
         .args(&["--demangle", &format!("--disassemble-symbols={func}")])
         .run()
-        .stdout_utf8();
-    let dump = dump.as_bytes();
+        .stdout();
 
     // Unique case, must succeed at one of two possible tests.
     // This is because frame pointers are optional, and them being enabled requires