sanebox: forward argv0

This commit is contained in:
2024-08-15 06:51:18 +00:00
parent 50b1d82b38
commit 87e9856497
2 changed files with 40 additions and 18 deletions

View File

@@ -4,7 +4,8 @@
buildPackages, buildPackages,
file, file,
gnugrep, gnugrep,
makeBinaryWrapper, gnused,
makeWrapper,
runCommandLocal, runCommandLocal,
runtimeShell, runtimeShell,
sanebox, sanebox,
@@ -60,7 +61,8 @@ let
# the ordering here is specific: inject our deps BEFORE the unwrapped program's # 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) # so that the unwrapped's take precendence and we limit interference (e.g. makeWrapper impl)
fakeSaneSandboxed fakeSaneSandboxed
makeBinaryWrapper gnugrep
makeWrapper
] ++ (unwrapped.nativeBuildInputs or []); ] ++ (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
@@ -73,15 +75,14 @@ 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() { # makeDocumentedCWrapper() {
# this is identical to nixpkgs' implementation, only replace execv with execvp, the latter which looks for the executable on PATH. # # this is identical to nixpkgs' implementation, only replace execv with execvp, the latter which looks for the executable on PATH.
local src docs # local src=$(makeCWrapper "$@")
src=$(makeCWrapper "$@") # src="''${src/return execv(/return execvp(}"
src="''${src/return execv(/return execvp(}" # local docs=$(docstring "$@")
docs=$(docstring "$@") # printf '%s\n\n' "$src"
printf '%s\n\n' "$src" # printf '%s\n' "$docs"
printf '%s\n' "$docs" # }
}
sandboxWrap() { sandboxWrap() {
local _dir="$1" local _dir="$1"
@@ -90,8 +91,7 @@ let
# N.B.: unlike stock `wrapProgram`, 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>` # though even so, the sandboxer still tries to preserve the $0 which it was invoked under
# 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)
@@ -101,7 +101,13 @@ let
else else
mv "$_dir/$_name" "$_dir/.sandboxed/" mv "$_dir/$_name" "$_dir/.sandboxed/"
fi fi
makeBinaryWrapper ${sanebox'} "$_dir/$_name" --suffix PATH : /run/current-system/sw/libexec/sanebox ${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} --add-flags "$_dir/.sandboxed/$_name" makeShellWrapper ${sanebox'} "$_dir/$_name" --suffix PATH : /run/current-system/sw/libexec/sanebox \
${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} \
--add-flags "$_dir/.sandboxed/$_name"
# `exec`ing a script with an interpreter will smash $0. instead, source it to preserve $0:
# - <https://github.com/NixOS/nixpkgs/issues/150841#issuecomment-995589961>
substituteInPlace "$_dir/$_name" \
--replace-fail 'exec ' 'source '
} }
crawlAndWrap() { crawlAndWrap() {

View File

@@ -94,6 +94,14 @@ netGateway=default
dns=() dns=()
# VAR -> VALUE map of environment variables to add to the sandboxed program's environment # VAR -> VALUE map of environment variables to add to the sandboxed program's environment
declare -A portalEnv declare -A portalEnv
argv0=
case "${0:-8}" in
("sanebox"|"/sanebox")
;;
(*)
argv0="$0"
;;
esac
# arguments to forward onto a specific backend (if that backend is active) # arguments to forward onto a specific backend (if that backend is active)
bwrapArgs=() bwrapArgs=()
@@ -501,6 +509,7 @@ parseArgs() {
# this lets the user do things like `mpv --sanebox-replace-cli sh` to enter a shell # this lets the user do things like `mpv --sanebox-replace-cli sh` to enter a shell
# with the sandbox that `mpv` would see. # with the sandbox that `mpv` would see.
parseArgsExtra=() parseArgsExtra=()
argv0=
;; ;;
(--sanebox-disable) (--sanebox-disable)
isDisable=1 isDisable=1
@@ -754,7 +763,8 @@ bwrapGetCli() {
done done
cliArgs=( cliArgs=(
"$_bwrap" \ "$_bwrap"
--argv0 "$argv0"
"${bwrapUnshareCgroup[@]}" "${bwrapUnshareCgroup[@]}"
"${bwrapUnshareIpc[@]}" "${bwrapUnshareIpc[@]}"
"${bwrapUnshareNet[@]}" "${bwrapUnshareNet[@]}"
@@ -921,7 +931,7 @@ capshonlyGetCli() {
locate _capsh "capsh" "$CAPSH_FALLBACK" locate _capsh "capsh" "$CAPSH_FALLBACK"
locate _env "env" "$ENV_FALLBACK" locate _env "env" "$ENV_FALLBACK"
local envArgs=() local envArgs=(-a "$argv0")
for envName in "${!portalEnv[@]}"; do for envName in "${!portalEnv[@]}"; do
envArgs+=("$envName=${portalEnv[$envName]}") envArgs+=("$envName=${portalEnv[$envName]}")
done done
@@ -984,7 +994,7 @@ pastaonlyIngestCapability() {
pastaonlyGetCli() { pastaonlyGetCli() {
cliArgs=( cliArgs=(
"/bin/sh" "-c" "/bin/sh" "-c"
"$pastaNetSetup exec"' "$0" "$@"' "$pastaNetSetup exec"' "$argv0" "$@"'
"${cliArgs[@]}" "${cliArgs[@]}"
) )
locate _pasta "pasta" "$PASTA_FALLBACK" locate _pasta "pasta" "$PASTA_FALLBACK"
@@ -1032,7 +1042,7 @@ noneIngestCapability() {
: :
} }
noneGetCli() { noneGetCli() {
: cliArgs=(-a "$argv0" "${cliArgs[@]}")
} }
@@ -1138,6 +1148,9 @@ parseArgsAndEnvironment() {
parseArgs "$@" parseArgs "$@"
cliArgs+=("${parseArgsExtra[@]}") cliArgs+=("${parseArgsExtra[@]}")
if [ -z "$argv0" ]; then
argv0=${cliArgs[0]}
fi
if [ -n "$SANEBOX_APPEND" ]; then if [ -n "$SANEBOX_APPEND" ]; then
parseArgs $SANEBOX_APPEND parseArgs $SANEBOX_APPEND
@@ -1175,6 +1188,9 @@ ingestForBackend() {
## TOPLEVEL EXECUTION ## TOPLEVEL EXECUTION
# no code evaluated before this point should be dependent on user args / environment. # no code evaluated before this point should be dependent on user args / environment.
# TODO: use `set -e`, only i'm using `return 1` in places for control flow.
set +e
parseArgsAndEnvironment "$@" parseArgsAndEnvironment "$@"
# variables meant to be inherited # variables meant to be inherited