programs: landlock: restrict the capabilities of sandboxed processes

This commit is contained in:
Colin 2024-01-27 09:49:51 +00:00
parent 3122434908
commit 4319dc58eb
2 changed files with 22 additions and 3 deletions

View File

@ -17,6 +17,7 @@ method=
firejailFlags=() firejailFlags=()
bwrapFlags=() bwrapFlags=()
landlockPaths= landlockPaths=
landlockCapshCapsArg=
debug() { debug() {
[ -n "$isDebug" ] && printf "[debug] %s" "$1" >&2 [ -n "$isDebug" ] && printf "[debug] %s" "$1" >&2
@ -261,7 +262,16 @@ landlockIngestProfile() {
debug "landlock doesn't implement profiles" debug "landlock doesn't implement profiles"
} }
landlockIngestCapability() { landlockIngestCapability() {
debug "landlock doesn't implement capabilities" # N.B. `capsh` parsing of `--caps=X` arg is idiosyncratic:
# - valid: `capsh --caps=CAP_FOO,CAP_BAR=eip -- <cmd>`
# - valid: `capsh --caps= -- <cmd>`
# - invalid: `capsh --caps=CAP_FOO,CAP_BAR -- <cmd>`
# - invalid: `capsh --caps==eip -- <cmd>`
if [ -z "$landlockCapshCapsArg" ]; then
landlockCapshCapsArg="cap_$1=eip"
else
landlockCapshCapsArg="cap_$1,$landlockCapshCapsArg"
fi
} }
landlockExec() { landlockExec() {
# other sandboxing methods would create fake /dev, /proc, /tmp filesystems # other sandboxing methods would create fake /dev, /proc, /tmp filesystems
@ -285,7 +295,15 @@ landlockExec() {
# landlockIngestRootPath '/dev/stderr' # landlockIngestRootPath '/dev/stderr'
# landlockIngestRootPath '/dev/stdin' # landlockIngestRootPath '/dev/stdin'
# landlockIngestRootPath '/dev/stdout' # landlockIngestRootPath '/dev/stdout'
PATH="$PATH:@landlockSandboxer@/bin" LL_FS_RO= LL_FS_RW="$landlockPaths" exec sandboxer "${cliArgs[@]}"
# landlock sandboxer has no native support for capabilities (except that it sets nonewprivs),
# so trampoline through `capsh` as well, to drop privs.
# N.B: capsh passes its arg to bash (via /nix/store/.../bash), which means you have to `-c "my command"` to
# invoke the actual user command.
PATH="$PATH:@landlockSandboxer@/bin:@libcap@/bin" LL_FS_RO= LL_FS_RW="$landlockPaths" exec \
sandboxer \
capsh "--caps=$landlockCapshCapsArg" -- \
-c "${cliArgs[*]}"
} }

View File

@ -2,6 +2,7 @@
, bubblewrap , bubblewrap
, firejail , firejail
, landlock-sandboxer , landlock-sandboxer
, libcap
, runtimeShell , runtimeShell
, substituteAll , substituteAll
, profileDir ? "/share/sane-sandboxed/profiles" , profileDir ? "/share/sane-sandboxed/profiles"
@ -10,7 +11,7 @@
let let
sane-sandboxed = substituteAll { sane-sandboxed = substituteAll {
src = ./sane-sandboxed; src = ./sane-sandboxed;
inherit bubblewrap firejail runtimeShell; inherit bubblewrap firejail libcap runtimeShell;
landlockSandboxer = landlock-sandboxer; landlockSandboxer = landlock-sandboxer;
firejailProfileDirs = "/run/current-system/sw/etc/firejail /etc/firejail ${firejail}/etc/firejail"; firejailProfileDirs = "/run/current-system/sw/etc/firejail /etc/firejail ${firejail}/etc/firejail";
# /run might be unavailable inside a container, so to support nested containers # /run might be unavailable inside a container, so to support nested containers