make-sandboxed: migrate to binary wrapper

This commit is contained in:
Colin 2024-07-03 19:35:56 +00:00
parent 4839a40205
commit e82feb9f71

View File

@ -4,7 +4,7 @@
buildPackages, buildPackages,
file, file,
gnugrep, gnugrep,
makeWrapper, makeBinaryWrapper,
runCommandLocal, runCommandLocal,
runtimeShell, runtimeShell,
sanebox, sanebox,
@ -56,10 +56,12 @@ let
# TODO: handle multi-output packages; until then, squash lib into the main output, particularly for `libexec`. # TODO: handle multi-output packages; until then, squash lib into the main output, particularly for `libexec`.
# (this line here only affects `inplace` style wrapping) # (this line here only affects `inplace` style wrapping)
outputs = lib.remove "lib" (unwrapped.outputs or [ "out" ]); outputs = lib.remove "lib" (unwrapped.outputs or [ "out" ]);
nativeBuildInputs = (unwrapped.nativeBuildInputs or []) ++ [ nativeBuildInputs = [
# the ordering here is specific: inject our deps BEFORE the unwrapped program's
# so that the unwrapped's take precendence and we limit interference (e.g. makeWrapper impl)
fakeSaneSandboxed fakeSaneSandboxed
makeWrapper makeBinaryWrapper
]; ] ++ (unwrapped.nativeBuildInputs or []);
disallowedReferences = (unwrapped.disallowedReferences or []) ++ [ disallowedReferences = (unwrapped.disallowedReferences or []) ++ [
# the fake sandbox gates itself behind SANEBOX_DISABLE, so if it did end up deployed # the fake sandbox gates itself behind SANEBOX_DISABLE, so if it did end up deployed
# then it wouldn't permit anything not already permitted. but it would still be annoying. # then it wouldn't permit anything not already permitted. but it would still be annoying.
@ -71,14 +73,25 @@ let
# my programs refer to sanebox by name, not path, which triggers an over-eager assertion in nixpkgs (so, mask that) # my programs refer to sanebox by name, not path, which triggers an over-eager assertion in nixpkgs (so, mask that)
: :
} }
makeDocumentedCWrapper() {
# this is identical to nixpkgs' implementation, only replace execv with execvp, the latter which looks for the executable on PATH.
local src docs
src=$(makeCWrapper "$@")
src="''${src/return execv(/return execvp(}"
docs=$(docstring "$@")
printf '%s\n\n' "$src"
printf '%s\n' "$docs"
}
sandboxWrap() { sandboxWrap() {
local _dir="$1" local _dir="$1"
local _name="$2" local _name="$2"
# N.B.: unlike `makeWrapper`, we place the unwrapped binary in a subdirectory and *preserve its name*. # N.B.: unlike stock `wrapProgram`, we place the unwrapped binary in a subdirectory and *preserve its name*.
# the upside of this is that for applications which read "$0" to decide what to do (e.g. busybox, git) # the upside of this is that for applications which read "$0" to decide what to do (e.g. busybox, git)
# they work as expected without any special hacks. # they work as expected without any special hacks.
# if desired, makeWrapper-style naming could be achieved by leveraging `exec -a <original_name>`. # if desired, makeWrapper-style naming could be achieved by leveraging `exec -a <original_name>`
# or `make-wrapper --inherit-argv0`
mkdir -p "$_dir/.sandboxed" mkdir -p "$_dir/.sandboxed"
if [[ "$(readlink $_dir/$_name)" =~ ^\.\./ ]]; then if [[ "$(readlink $_dir/$_name)" =~ ^\.\./ ]]; then
# relative links which ascend a directory (into a non-bin/ directory) # relative links which ascend a directory (into a non-bin/ directory)
@ -88,7 +101,7 @@ let
else else
mv "$_dir/$_name" "$_dir/.sandboxed/" mv "$_dir/$_name" "$_dir/.sandboxed/"
fi fi
makeShellWrapper ${sanebox'} "$_dir/$_name" --inherit-argv0 ${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} --add-flags "$_dir/.sandboxed/$_name" makeBinaryWrapper ${sanebox'} "$_dir/$_name" ${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} --add-flags "$_dir/.sandboxed/$_name"
} }
crawlAndWrap() { crawlAndWrap() {