Rust – Static PIE and ASLR for the x86_64-unknown-linux-musl Target

Posted by Harald Hoyer on 23 June 2020

Thanks to PR #70740 and a lot of work of Vadim Petrochenkov, for current rust nightly the default binary output of the x86_64-unknown-linux-musl target is a static position independent executable (static-pie) with address space layout randomization (ASLR) on execution.

hello.rs:

fn main() {
    println!("main = {:?}", &main as *const _);
}

Current stable rust 1.44.1 produces the usual static elf binary:

$ rustc --version
  rustc 1.44.1 (c7087fe00 2020-06-17)

$ rustc --target x86_64-unknown-linux-musl hello.rs

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=3f44a4c3315d4c7c94c64b332a3fb3e604a7c066, with debug_info, not stripped

$ ./hello
main = 0x43b008

$ ./hello
main = 0x43b008

Current nightly rust 1.46.0 produces a static-pie with ASLR:

$ rustc +nightly --version
rustc 1.46.0-nightly (6bb3dbfc6 2020-06-22)

$ rustc +nightly --target x86_64-unknown-linux-musl hello.rs

$ file hello
hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=9592de3bfd3e9b71296edb494f1eac23958a4c59, with debug_info, not stripped

$ ./hello
main = 0x7f7310574008

$ ./hello
main = 0x7fb552b0c008

To produce the old behaviour use -C relocation-model=static:

$ rustc +nightly -C relocation-model=static --target x86_64-unknown-linux-musl hello.rs

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=699001ae8b33f5721fda2ddb8442c161d266309e, with debug_info, not stripped

$ ./hello
main = 0x439060

$ ./hello
main = 0x439060

Discussion on Reddit.