make-sandboxed: fix several edge-cases for e.g. brave, firefox, especially around handling of wrapped binaries
This commit is contained in:
@@ -156,7 +156,9 @@ let
|
|||||||
for item in "''${items[@]}"; do
|
for item in "''${items[@]}"; do
|
||||||
if [ "$item" != . ] && [ "$item" != .. ]; then
|
if [ "$item" != . ] && [ "$item" != .. ]; then
|
||||||
local target="$_dir/$item"
|
local target="$_dir/$item"
|
||||||
if [ -x "$target" ] && ! [ -d "$target" ]; then
|
if [ -d "$target" ]; then
|
||||||
|
crawlAndWrap "$output" "$target"
|
||||||
|
elif [ -x "$target" ] && [[ "$item" != .* ]]; then
|
||||||
# in the case of symlinks, deref until we find the real file, or the symlink points outside the package
|
# in the case of symlinks, deref until we find the real file, or the symlink points outside the package
|
||||||
target=$(derefWhileInSameOutput "$output" "$target")
|
target=$(derefWhileInSameOutput "$output" "$target")
|
||||||
target=$(findUnwrapped "$target")
|
target=$(findUnwrapped "$target")
|
||||||
@@ -165,10 +167,8 @@ let
|
|||||||
local bin=$(basename "$target")
|
local bin=$(basename "$target")
|
||||||
sandboxWrap "$parent" "$bin"
|
sandboxWrap "$parent" "$bin"
|
||||||
fi
|
fi
|
||||||
elif [ -d "$target" ]; then
|
|
||||||
crawlAndWrap "$output" "$target"
|
|
||||||
fi
|
fi
|
||||||
# ignore all non-binaries
|
# ignore all non-binaries or "hidden" binaries (to avoid double-wrapping)
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -196,15 +196,14 @@ let
|
|||||||
;
|
;
|
||||||
|
|
||||||
# helper used for `wrapperType == "wrappedDerivation"` which simply symlinks all a package's binaries into a new derivation
|
# helper used for `wrapperType == "wrappedDerivation"` which simply symlinks all a package's binaries into a new derivation
|
||||||
symlinkBinaries = pkgName: package: (runCommandLocal "${pkgName}-bin-only" {
|
symlinkDirs = suffix: symlinkRoots: pkgName: package: (runCommandLocal "${pkgName}-${suffix}" {
|
||||||
|
env.symlinkRoots = lib.concatStringsSep " " symlinkRoots;
|
||||||
nativeBuildInputs = [ gnused ];
|
nativeBuildInputs = [ gnused ];
|
||||||
} ''
|
} ''
|
||||||
set -e
|
set -e
|
||||||
symlinkPath() {
|
symlinkPath() {
|
||||||
if [ -e "$out/$1" ]; then
|
if [ -e "$out/$1" ]; then
|
||||||
: # already linked. may happen when e.g. the package has bin/foo, and sbin -> bin.
|
: # already linked. may happen when e.g. the package has bin/foo, and sbin -> bin.
|
||||||
elif ! [ -x "${package}/$1" ]; then
|
|
||||||
: # not a binary, nor a directory (-x) which could contain binaries
|
|
||||||
elif [ -L "${package}/$1" ]; then
|
elif [ -L "${package}/$1" ]; then
|
||||||
local target=$(readlink "${package}/$1")
|
local target=$(readlink "${package}/$1")
|
||||||
if [[ "$target" =~ ^${package}/ ]]; then
|
if [[ "$target" =~ ^${package}/ ]]; then
|
||||||
@@ -235,7 +234,7 @@ let
|
|||||||
mkdir -p "$out/$1"
|
mkdir -p "$out/$1"
|
||||||
items=($(ls -a "${package}/$1"))
|
items=($(ls -a "${package}/$1"))
|
||||||
for item in "''${items[@]}"; do
|
for item in "''${items[@]}"; do
|
||||||
if [ "$item" != . ] && [ "$item" != .. ]; then
|
if [ "$item" != . ] && [ "$item" != .. ] && [[ "$item" != .* ]]; then
|
||||||
symlinkPath "$1/$item"
|
symlinkPath "$1/$item"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -244,16 +243,22 @@ let
|
|||||||
ln -s "${package}/$1" "$out/$1"
|
ln -s "${package}/$1" "$out/$1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
symlinkPath bin
|
mkdir -p "$out"
|
||||||
symlinkPath sbin
|
_symlinkRoots=($symlinkRoots)
|
||||||
symlinkPath libexec
|
for root in "''${_symlinkRoots[@]}"; do
|
||||||
# allow downstream wrapping to hook this (and thereby actually wrap the binaries)
|
echo "crawling top-level directory for symlinking: $root"
|
||||||
|
symlinkPath "$root"
|
||||||
|
done
|
||||||
|
# allow downstream wrapping to hook this (and thereby actually wrap binaries, etc)
|
||||||
|
runHook postInstall
|
||||||
runHook postFixup
|
runHook postFixup
|
||||||
'').overrideAttrs (_: {
|
'').overrideAttrs (_: {
|
||||||
# specifically, preserve meta.priority
|
# specifically, preserve meta.priority
|
||||||
meta = extractMeta package;
|
meta = extractMeta package;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
symlinkBinaries = symlinkDirs "bin-only" [ "bin" "sbin" "libexec" ];
|
||||||
|
|
||||||
# helper used for `wrapperType == "wrappedDerivation"` which ensures that any copied/symlinked share/ files (like .desktop) files
|
# helper used for `wrapperType == "wrappedDerivation"` which ensures that any copied/symlinked share/ files (like .desktop) files
|
||||||
# don't point to the unwrapped binaries.
|
# don't point to the unwrapped binaries.
|
||||||
# other important files it preserves:
|
# other important files it preserves:
|
||||||
@@ -281,12 +286,9 @@ let
|
|||||||
}
|
}
|
||||||
|
|
||||||
# remove any files which exist in sandoxedBin (makes it possible to sandbox /opt-style packages)
|
# remove any files which exist in sandoxedBin (makes it possible to sandbox /opt-style packages)
|
||||||
# also remove any files which would be "hidden". mostly useful for /opt-style packages which contain nix-wrapped binaries.
|
|
||||||
removeUnwanted() {
|
removeUnwanted() {
|
||||||
local file_=$(basename "$1")
|
local file_=$(basename "$1")
|
||||||
if [[ "$file_" == .* ]]; then
|
if [ -f "$out/$1" ] || [ -L "$out/$1" ]; then
|
||||||
rm -r "$out/$1"
|
|
||||||
elif [ -f "$out/$1" ] || [ -L "$out/$1" ]; then
|
|
||||||
if [ -e "${sandboxedBin}/$1" ]; then
|
if [ -e "${sandboxedBin}/$1" ]; then
|
||||||
rm "$out/$1"
|
rm "$out/$1"
|
||||||
fi
|
fi
|
||||||
@@ -320,8 +322,6 @@ let
|
|||||||
passthru = (prevAttrs.passthru or {}) // {
|
passthru = (prevAttrs.passthru or {}) // {
|
||||||
# check that sandboxedNonBin references only sandboxed binaries, and never the original unsandboxed binaries.
|
# check that sandboxedNonBin references only sandboxed binaries, and never the original unsandboxed binaries.
|
||||||
# do this by dereferencing all sandboxedNonBin symlinks, and making `unsandboxed` a disallowedReference.
|
# do this by dereferencing all sandboxedNonBin symlinks, and making `unsandboxed` a disallowedReference.
|
||||||
# further, since the sandboxed binaries intentionally reference the unsandboxed binaries,
|
|
||||||
# we have to patch those out as a way to whitelist them.
|
|
||||||
checkSandboxed = let
|
checkSandboxed = let
|
||||||
sandboxedNonBin = fixHardcodedRefs unsandboxed sandboxedBin unsandboxedNonBin;
|
sandboxedNonBin = fixHardcodedRefs unsandboxed sandboxedBin unsandboxedNonBin;
|
||||||
in runCommandLocal "${sandboxedNonBin.name}-check-sandboxed"
|
in runCommandLocal "${sandboxedNonBin.name}-check-sandboxed"
|
||||||
@@ -342,25 +342,7 @@ let
|
|||||||
# patch them to use the sandboxed binaries,
|
# patch them to use the sandboxed binaries,
|
||||||
# and add some passthru metadata to enforce no lingering references to the unsandboxed binaries.
|
# and add some passthru metadata to enforce no lingering references to the unsandboxed binaries.
|
||||||
sandboxNonBinaries = pkgName: unsandboxed: sandboxedBin: let
|
sandboxNonBinaries = pkgName: unsandboxed: sandboxedBin: let
|
||||||
sandboxedWithoutFixedRefs = (runCommandLocal "${pkgName}-sandboxed-non-binary" {
|
sandboxedWithoutFixedRefs = symlinkDirs "non-bin" [ "etc" "share" ] pkgName unsandboxed;
|
||||||
nativeBuildInputs = [ xorg.lndir ];
|
|
||||||
} ''
|
|
||||||
set -e
|
|
||||||
mkdir "$out"
|
|
||||||
# link in a limited subset of the directories.
|
|
||||||
# lib/ is the primary one to avoid, because of shared objects that would be unsandboxed if dlopen'd.
|
|
||||||
# all other directories are safe-ish, because they won't end up on PATH or LDPATH.
|
|
||||||
for dir in etc share; do
|
|
||||||
if [ -e "${unsandboxed}/$dir" ]; then
|
|
||||||
mkdir "$out/$dir"
|
|
||||||
lndir "${unsandboxed}/$dir" "$out/$dir"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
runHook postInstall
|
|
||||||
'').overrideAttrs (_: {
|
|
||||||
# specifically for meta.priority, though it shouldn't actually matter here.
|
|
||||||
meta = extractMeta unsandboxed;
|
|
||||||
});
|
|
||||||
in fixHardcodedRefs unsandboxed sandboxedBin sandboxedWithoutFixedRefs;
|
in fixHardcodedRefs unsandboxed sandboxedBin sandboxedWithoutFixedRefs;
|
||||||
|
|
||||||
# take the nearly-final sandboxed package, with binaries and all else, and
|
# take the nearly-final sandboxed package, with binaries and all else, and
|
||||||
|
Reference in New Issue
Block a user