12 releases
Uses new Rust 2024
| new 0.6.0 | Feb 17, 2026 |
|---|---|
| 0.5.1 | Feb 4, 2025 |
| 0.5.0 | Dec 14, 2024 |
| 0.4.1 | Nov 25, 2024 |
| 0.1.1 | Mar 25, 2024 |
#31 in Build Utils
53KB
837 lines
build-wrap
A linker replacement to help protect against malicious build scripts
build-wrap "re-links" a build script so that it is executed under another command. By default, the command is Bubblewrap (Linux) or sandbox-exec (macOS), though this is configurable. See Environment variables that build-wrap reads and How build-wrap works for more information.
Installation
Installing build-wrap requires two steps:
- Install
build-wrapwith Cargo:cargo install build-wrap - Create a
.cargo/config.tomlfile in your home directory with the following contents:[target.'cfg(all())'] linker = "build-wrap"
Ubuntu 24.04
Ubuntu's default AppArmor profiles changed with version 24.04. The changes affect Bubblewrap, which in turn affect build-wrap. Thus, installing build-wrap on Ubuntu 24.04 requires some additional steps:
sudo apt install apparmor-profiles
sudo cp /usr/share/apparmor/extra-profiles/bwrap-userns-restrict /etc/apparmor.d
sudo systemctl reload apparmor
Note that following these additional steps, Bubblewrap still runs unprivileged. More information on AppArmor profiles can be found on Ubuntu Server and the Ubuntu Community Wiki.
Environment variables that build-wrap reads
Note that the below environment variables are read when a build script is linked. So, for example, changing BUILD_WRAP_CMD will not change the command used to execute already linked build scripts.
-
BUILD_WRAP_ALLOW: When set to a value other than0,build-wrapuses the following weakened strategy. If running a build script underBUILD_WRAP_CMDfails, report the failure and rerun the build script normally.Note that to see the reported failures, you must invoke Cargo with the
-vv("very verbose") flag, e.g.:BUILD_WRAP_ALLOW=1 cargo build -vvTo disable sandboxing entirely for specific directories or packages, use
$HOME/.config/build-wrap/config.toml(see below). -
BUILD_WRAP_CMD: Command used to execute a build script. Linux default:-
With comments:
bwrap --ro-bind / / # Allow read-only access everywhere --dev-bind /dev /dev # Allow device access --bind {OUT_DIR} {OUT_DIR} # Allow write access to `OUT_DIR` --bind /tmp /tmp # Allow write access to /tmp --unshare-net # Deny network access {} # Build script path -
On one line (for copying-and-pasting):
bwrap --ro-bind / / --dev-bind /dev /dev --bind {OUT_DIR} {OUT_DIR} --bind /tmp /tmp --unshare-net {}
Note that
bwrapis Bubblewrap.macOS default:
sandbox-exec -f {BUILD_WRAP_PROFILE_PATH} {}See Environment variables that
build-wraptreats as set regardingBUILD_WRAP_PROFILE_PATH. -
-
BUILD_WRAP_LD: Linker to use. Default:cc -
BUILD_WRAP_PROFILE: macOS only.build-wrapexpandsBUILD_WRAP_PROFILEas it wouldBUILD_WRAP_CMD, and writes the results to a temporary file.BUILD_WRAP_PROFILE_PATHthen expands to the absolute path of that temporary file. Default:(version 1) (deny default) (allow file-read*) ;; Allow read-only access everywhere (allow file-write* (subpath "/dev")) ;; Allow write access to /dev (allow file-write* (subpath "{OUT_DIR}")) ;; Allow write access to `OUT_DIR` (allow file-write* (subpath "{TMPDIR}")) ;; Allow write access to `TMPDIR` (allow file-write* (subpath "{PRIVATE_TMPDIR}")) ;; Allow write access to `PRIVATE_TMPDIR` (see below) (allow process-exec) ;; Allow `exec` (allow process-fork) ;; Allow `fork` (allow sysctl-read) ;; Allow reading kernel state (deny network*) ;; Deny network access
$HOME/.config/build-wrap/config.toml
If a file at $HOME/.config/build-wrap/config.toml exists, build-wrap reads it to determine which directories and packages should be allowed to build without sandboxing.
The file supports [allow] and [ignore] sections, which are treated as synonyms:
[allow]
directories = ["/home/user/project-a"]
packages = ["aws-lc-fips-sys"]
[ignore]
directories = ["/home/user/project-b"]
packages = ["svm-rs-builds"]
directories: A list of directory paths. Ifcargo buildis run from within a listed directory (or any subdirectory),build-wrapwill not sandbox the build scripts.packages: A list of package names. Build scripts belonging to listed packages will not be sandboxed.
Both sections are merged, so entries from [allow] and [ignore] are combined.
For example, if you frequently build in a project that has dependencies requiring unrestricted build scripts:
mkdir -p "$HOME/.config/build-wrap"
cat > "$HOME/.config/build-wrap/config.toml" << 'EOF'
[allow]
packages = ["svm-rs-builds"]
EOF
Environment variables that build-wrap treats as set
Note that we say "treats as set" because these are considered only when BUILD_WRAP_CMD is expanded.
-
BUILD_WRAP_PROFILE_PATH: Expands to the absolute path of a temporary file containing the expanded contents ofBUILD_WRAP_PROFILE. -
PRIVATE_TMPDIR: IfTMPDIRis set to a path in/private(as is typical on macOS), thenPRIVATE_TMPDIRexpands to that path. This is needed for some build scripts that usecc-rs, though the exact reason it is needed is still unknown.
How BUILD_WRAP_CMD is expanded
{}is replaced with the path of a renamed copy of the original build script.{VAR}is replaced with the value of environment variableVAR.{{is replaced with{.}}is replaced with}.\followed by a whitespace character is replaced with that whitespace character.\\is replaced with\.
How build-wrap works
When invoked, build-wrap does the following:
- Link normally using
BUILD_WRAP_LD. - Parse the arguments to determine whether the output file is a build script.
- If not, stop; otherwise, proceed.
- Let
Bbe the build script's original name. - Rename the build script to a fresh, unused name
B'. - At
B, create a "wrapped" version of the build script whose behavior is described next.
The "wrapped" version of the build script does the following when invoked:
- Expand
BUILD_WRAP_CMDin the manner described above, with{}expanding toB'. - Execute the expanded command.
Goals
- Aside from configuration and dealing with an occasional warning,
build-wrapshould not require a user to adjust their normal workflow.
Dependencies
~4–11MB
~227K SLoC