Summary
There should be a new profile setting named like sanitize-paths
to sanitise all host filesystem dependent paths (e.g. $PWD
and /home/username/.cargo
) that may be embedded in the compilation output, backed up by --remap-path-prefix
in rustc
. This should be enabled by default for release
profile.
Motivation
-
Privacy. Most of the times the paths will include the username, and
release
binaries built on a crate maitainer's machine may be distributed. Additionally, some CI (such as GitLab CI) checks out the repo under a path where it may include things that really aren't meant to be public. Without sanitising the path by default, this may be inadvertently leaked. -
Facillitating binary reproducibility. In the below example, I was able to produce binary equivalent executables on two different x86_64 Linux machines. Some very non-trivial programs can also be made easily reproducible with the same
RUSTFLAGS
, such as ogham/dog. Path remapping alone will not guarantee reproducible builds on everthing (for instance,cargo
built from source are still different on those two machines), but this simple change probably could cover a lot of cases.
The Problem
Currently, binaries (and libraries) built with cargo have a lot of local filesystem dependent paths baked in. They mostly exist inside panic messages.
With an example:
Cargo.toml
:
[package]
name = "rfc"
version = "0.1.0"
edition = "2018"
[dependencies]
rand = "0.8.0"
src/main.rs
use rand::prelude::*;
fn main() {
let r: f64 = rand::thread_rng().gen();
println!("{}", r);
}
Then run
$ cargo build --release
$ strings target/release/rfc | grep $HOME
could not initialize thread_rng: /home/cbeuw/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.8.3/src/rngs/thread.rs
/home/cbeuw/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_chacha-0.3.0/src/guts.rsdescription() is deprecated; use Display
/home/cbeuw/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/util_libc.rs
However, if we manually remap the paths to the working directory and .cargo
folder by supplying --remap-path-prefix
to rustc (Note this won't fully work if you have rust-src
component installed until #73167 is fixed. There is a fix in progress. This post assumes rust-src
isn't installed.):
$ RUSTFLAGS="--remap-path-prefix=$PWD=. --remap-path-prefix=$CARGO_HOME=cargo_home" cargo build --release
$ strings target/release/rfc | grep registry
Path to the cargo registry will be remapped:
could not initialize thread_rng: cargo_home/registry/src/github.com-1ecc6299db9ec823/rand-0.8.3/src/rngs/thread.rs
With a new profile setting called sanitize-paths
or similar, this can be done automatically so users need not to manually discover which paths should to be remapped. It's also logical to have this done by default when the user does cargo build --release
.
Reference-level explanation
With sanitize-paths = true
, the following paths will be remapped, in the following order
- The working directory under which the
cargo
command is invoked. This will be remapped to.
- Cargo's home directory will be remapped to
/cargo
on Unix and\\cargo
on Windows - Rust's sysroot will be remapped to
/sysroot
on Unix and\\sysroot
on Windows - Any other package's root will be remapped to
/[package name]
on Unix and\\[package name]
on Windows
For instance:
-
/home/cbeuw/rfc/src/main.rs
->./src/main.rs
-
/home/.cargo/registry
->/cargo/registry
-
/home/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib
->/sysroot/lib
-
/home/cbeuw/path/dependencies/foo/src/lib.rs
->/foo/src/lib.rs
(TODO: should we ignore the path separator/prefix differences on the last two and make it the same across board?)
Drawbacks
For source files under Cargo's home or Rust's sysroot, panic messages in release
builds will no longer print a valid path. However, source files in the working directory, presumably ones the user is working on, will still have the correct relative path. The overall impact should be small and confusion unlikely.