Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hermetic build mode #9506

Open
Tracked by #84
matklad opened this issue May 21, 2021 · 5 comments
Open
Tracked by #84

Hermetic build mode #9506

matklad opened this issue May 21, 2021 · 5 comments
Labels
A-reproducibility Area: reproducible / deterministic builds C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` E-hard Experience: Hard S-needs-rfc Status: Needs an RFC to make progress.

Comments

@matklad
Copy link
Member

matklad commented May 21, 2021

Meta: this should be an RFC, but I am unlikely to write one soon. Creating mostly to coordinate discussion.

Problem: today, it's possible to get byte-for-byte identical results compilation results (especially with wasm), but it is impossible to guarantee, because ambient environment (~/.cargo/config, CARGO_HOME, etc) can influence the build. That is, builds are reproducible, but are not hermetic. As a specific example, if I publish a wasm project with Cargo.lock and rust-toolchain.toml, folks running cargo build will generally get the same results, unless someone has RUSTFLAGS set.

Solution: add a mechanism to Cargo to out-out of ambient environment. Strawman proposal -- when --hermetic flag is passed, cargo guarantees that the builds are only affected by the contents of the current working directory.

I don't know an exhaustive list of things that hypothetical --hermetic should forbid, but here are some candidates:

  • access to .cargo/config outside of the current directory
  • access to env vars like RUSTFLAGS, unless explicitly opted into (a-la --hermetic --allow-env RUSTFLAGS)
  • access to PATH? This intersects with rustup. compiler version obviously affects the results, and we need compiler, so PATH is importaet. Perhaps printing rustc -vv during hermetic build is the way to go?
  • --hermetic should imply --locked (valid lockfile)
  • --hermetic should not imply --frozen. That is, Cargo should be able to fetch sources from the internet (and uses CARGO_HOME for caches), as long as it guarantees that the result is reproducible.

A related feature is #7894, #7887. It allows to control .cargo/config specifically. I, however, feel that we want to make a more specific promise about properties (hermeticity), and tread config handling as an implementation detail.

cc @jsgf

@matklad matklad added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label May 21, 2021
@jsgf
Copy link
Contributor

jsgf commented May 24, 2021

access to PATH? This intersects with rustup. compiler version obviously affects the results, and we need compiler, so PATH is importaet. Perhaps printing rustc -vv during hermetic build is the way to go?

It's definitely an antipattern to use env!() or std::env::var at build time to get PATH as a runtime default, but it's not unknown. Similarly, searching for libraries at build time with LD_LIBRARY_PATH or similar.

In general, should cargo control what env vars are available to builds? I have a proposal for rustc to make env control much tighter, by supplying a logical environment to rustc via --env parameters, so that the effective environment is completely controllable (including things like overriding PATH even if its needed to actually execute rustc).

@ehuss ehuss added the A-reproducibility Area: reproducible / deterministic builds label Jun 3, 2021
@matklad
Copy link
Member Author

matklad commented Jul 6, 2021

--hermetic should also pass appropriate --remap-path-prefix: #5505

I think the current state of the art is to export RUST_FLAGS="--remap-path-prefix $PWD=/pwd --remap-path-prefix $CARGO_HOME=/cargo_home"

@LegNeato
Copy link

LegNeato commented Jul 8, 2021

access to PATH? This intersects with rustup. compiler version obviously affects the results, and we need compiler, so PATH is importaet. Perhaps printing rustc -vv during hermetic build is the way to go?

Perhaps require a rust-toolchain.toml?

@bjorn3
Copy link
Member

bjorn3 commented Jul 9, 2021

What about the linker or the C compiler? Different versions can result in different compilation outputs. Should rust-lld be forcefully used instead of the platform linker (probably uncontroversial) and usage of a C compiler prevented (probably controversial)?

Should this use seccomp-bpf or other os mechanisms to prevent not just filesystem access, but as much system calls as possible?

Should RUSTFLAGS=-Ctarget-cpu=native be ignored? Should other RUSTFLAGS or RUSTC be ignored?

@FloLo100
Copy link

People might not only want to protect the binary from side-effects of the build-system but also the build-system from side effects of building (and therefore subsequent builds on the same system) when using the catchphrase "hermetic builds".

To offer these features thoroughly, the use of container-solutions (Docker/linux-namespaces, I'm unsure what exists on Windows or MacOS) is necessary. The question then is, whether cargo itself should offer a mode where it spawns such containers, or if merely compatibility and ease of use of third-party tools that spawn build-containers should be the goal here. It's important to note, that container-in-container won't work. So if we spawn containers, people cannot put cargo into a container while using that mode.

At my company we have started to implement a container solution using bubblewrap-containers. I could share our development if that's the direction we want to go into.

@weihanglo weihanglo added E-hard Experience: Hard S-needs-rfc Status: Needs an RFC to make progress. labels Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-reproducibility Area: reproducible / deterministic builds C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` E-hard Experience: Hard S-needs-rfc Status: Needs an RFC to make progress.
Projects
None yet
Development

No branches or pull requests

7 participants