Crates.io | build-wrap |
lib.rs | build-wrap |
version | 0.3.0 |
source | src |
created_at | 2024-03-14 16:31:31.155082 |
updated_at | 2024-05-07 11:22:47.485791 |
description | Help protect against malicious build scripts |
homepage | |
repository | https://github.com/trailofbits/build-wrap |
max_upload_size | |
id | 1173520 |
size | 59,981 |
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.
Installing build-wrap
requires two steps:
build-wrap
with Cargo:
cargo install build-wrap
.cargo/config.toml
file in your home directory with the following contents:
[target.'cfg(all())']
linker = "build-wrap"
build-wrap
readsBUILD_WRAP_ALLOW
: When set to a value other than 0
, build-wrap
uses the following weakened strategy. If running a build script under BUILD_WRAP_CMD
fails, 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 -vv
BUILD_WRAP_CMD
: Command used to execute a build script. Linux default:
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
Note that bwrap
is Bubblewrap.
macOS default:
sandbox-exec -p
(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
{} # Build script path
Note that (version\ 1)\ ... (deny\ network*)
expands to a single string (see How BUILD_WRAP_CMD
is expanded below).
BUILD_WRAP_LD
: Linker to use. Default: cc
Note that the above environment variables are read when the 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
treats as setNote that we say "treats as set" because these are considered only when BUILD_WRAP_CMD
is expanded.
PRIVATE_TMPDIR
: If TMPDIR
is set to a path in /private
(as is typical on macOS), then PRIVATE_TMPDIR
expands to that path. This is needed for some build scripts that use cc-rs
, though the exact reason it is needed is still unknown.BUILD_WRAP_CMD
is expanded{}
is replaced with the path of a copy of the original build script.{VAR}
is replaced with the value of environment variable VAR
.{{
is replaced with {
.}}
is replaced with }
.\
followed by a whitespace character is replaced with that whitespace character.\\
is replaced with \
.build-wrap
worksWhen invoked, build-wrap
does the following:
BUILD_WRAP_LD
.B
with its "wrapped" version B'
, described next.Given a build script B
, its "wrapped" version B'
contains a copy of B
and does the following when invoked:
B
. (Recall: B'
contains a copy of B
).BUILD_WRAP_CMD
in the manner described above.build-wrap
should not require a user to adjust their normal workflow.