diff options
author | Ilya K <me@0upti.me> | 2024-04-16 05:33:41 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@lix> | 2024-04-16 05:33:41 +0000 |
commit | 6d79aa3d70a65b9eba2982325a8b6d149cbef453 (patch) | |
tree | 093f2cbdcc8afd6b90dcccace34ca73e150ee784 | |
parent | a41abb4594d951339d3b4346251ddbc5364c0a04 (diff) | |
parent | effc28f6f5621cf0c32716f2137f9aee7567aa48 (diff) |
Merge "libstore/build: set NO_NEW_PRIVS for the sandbox" into main
-rw-r--r-- | src/libstore/build/local-derivation-goal.cc | 5 | ||||
-rw-r--r-- | tests/nixos/default.nix | 2 | ||||
-rw-r--r-- | tests/nixos/root-in-sandbox/default.nix | 15 | ||||
-rw-r--r-- | tests/nixos/root-in-sandbox/package.nix | 8 | ||||
-rw-r--r-- | tests/nixos/symlink-resolvconf.nix | 1 | ||||
-rw-r--r-- | tests/nixos/util.nix | 23 |
6 files changed, 54 insertions, 0 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 193fc598e..35e7ce907 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -41,6 +41,7 @@ #include <sched.h> #include <sys/param.h> #include <sys/mount.h> +#include <sys/prctl.h> #include <sys/syscall.h> #if HAVE_SECCOMP #include <seccomp.h> @@ -1949,6 +1950,10 @@ void LocalDerivationGoal::runChild() throw SysError("setuid failed"); setUser = false; + + // Make sure we can't possibly gain new privileges in the sandbox + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) + throw SysError("PR_SET_NO_NEW_PRIVS failed"); } #endif diff --git a/tests/nixos/default.nix b/tests/nixos/default.nix index 14fc0da81..3ef1217ac 100644 --- a/tests/nixos/default.nix +++ b/tests/nixos/default.nix @@ -160,4 +160,6 @@ in fetch-git = runNixOSTestFor "x86_64-linux" ./fetch-git; symlinkResolvconf = runNixOSTestFor "x86_64-linux" ./symlink-resolvconf.nix; + + rootInSandbox = runNixOSTestFor "x86_64-linux" ./root-in-sandbox; } diff --git a/tests/nixos/root-in-sandbox/default.nix b/tests/nixos/root-in-sandbox/default.nix new file mode 100644 index 000000000..110d83f86 --- /dev/null +++ b/tests/nixos/root-in-sandbox/default.nix @@ -0,0 +1,15 @@ +let + inherit (import ../util.nix) mkNixBuildTest; +in mkNixBuildTest { + name = "root-in-sandbox"; + extraMachineConfig = { pkgs, ... }: { + security.wrappers.ohno = { + owner = "root"; + group = "root"; + setuid = true; + source = "${pkgs.coreutils}/bin/whoami"; + }; + nix.settings.extra-sandbox-paths = ["/run/wrappers/bin"]; + }; + expressionFile = ./package.nix; +} diff --git a/tests/nixos/root-in-sandbox/package.nix b/tests/nixos/root-in-sandbox/package.nix new file mode 100644 index 000000000..a1069160c --- /dev/null +++ b/tests/nixos/root-in-sandbox/package.nix @@ -0,0 +1,8 @@ +{ runCommand }: +runCommand "cant-get-root-in-sandbox" {} '' + if /run/wrappers/bin/ohno; then + echo "Oh no! We're root in the sandbox!" + exit 1 + fi + touch $out +'' diff --git a/tests/nixos/symlink-resolvconf.nix b/tests/nixos/symlink-resolvconf.nix index 47df27524..6a7d24601 100644 --- a/tests/nixos/symlink-resolvconf.nix +++ b/tests/nixos/symlink-resolvconf.nix @@ -1,5 +1,6 @@ { pkgs, ... }: let + # Can't use the cool helper because inputDerivation does not work with FODs :( checkResolvconfInSandbox = pkgs.runCommand "resolvconf-works-in-sandbox" { # must be an FOD to have a resolv.conf in the first place outputHash = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; diff --git a/tests/nixos/util.nix b/tests/nixos/util.nix new file mode 100644 index 000000000..0c51cc075 --- /dev/null +++ b/tests/nixos/util.nix @@ -0,0 +1,23 @@ +{ + mkNixBuildTest = { name, expressionFile, extraMachineConfig ? {} }: + { lib, pkgs, ... }: + { + inherit name; + + nodes.machine = { + imports = [extraMachineConfig]; + nix.nixPath = ["nixpkgs=${pkgs.path}"]; + nix.settings.substituters = lib.mkForce []; + virtualisation.additionalPaths = [ + expressionFile + (pkgs.callPackage expressionFile {}).inputDerivation + ]; + }; + + testScript = { nodes }: '' + start_all() + + machine.succeed('nix-build --expr "let pkgs = import <nixpkgs> {}; in pkgs.callPackage ${expressionFile} {}"') + ''; + }; +} |