Description
There seems to be a significant compile time regression when using the LVI mitigation passes on some crates. The smallest case I could come up with is:
#[macro_use] extern crate crunchy;
#[macro_use] extern crate uint;
//construct_uint!(UINT, 1);
//construct_uint!(UINT, 2);
//construct_uint!(UINT, 4);
//construct_uint!(UINT, 8);
construct_uint!(UINT, 16);
fn main() {
let a = UINT::from_dec_str("10").unwrap();
let b = UINT::from_dec_str("20").unwrap();
println!("a * b = {}", ((a * b - b ) / a).as_u32());
}
TOML:
[package]
name = "lvitest"
version = "0.1.0"
edition = "2018"
[dependencies]
crunchy = { version = "0.1" }
uint = { version = "0.2.1" }
This happens with the x86_64-fortanix-unknown-sgx
target, but also without it with the following codegen options (.cargo/config.toml
):
[build]
rustflags = ["-C", "link-dead-code", "-C", "llvm-args=--x86-experimental-lvi-inline-asm-hardening", "-C", "target-feature=+lvi-cfi,+lvi-load-hardening"]
Expected:
Without the config.toml
on a vanilla rustup-installed nightly, a cargo clean && cargo build
takes a second or two.
Instead:
With LVI mitigations enabled, compile time explodes to about 35 minutes on my machine.
If I disable linking dead code, it drops to 2 minutes, although that's mostly because the sample above is simple. Using shorter uints (e.g. the ones commented out above) makes it drop further still, but compile time still noticeably depends on the uint length.
Using a newer version of the uint
crate (e.g. 0.4.1) also seems to solve the issue. The main difference that I could find is that the older version uses inline assembly. Not sure if that's a red herring or not.
Meta
rustc --version --verbose
:
rustc 1.47.0-nightly (8ad7bc3f4 2020-07-21)
binary: rustc
commit-hash: 8ad7bc3f428300aee6764f6e23527e19eb235e81
commit-date: 2020-07-21
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0