diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc index 01a133766d9..168bf45319b 100644 --- a/src/libstore/unix/build/local-derivation-goal.cc +++ b/src/libstore/unix/build/local-derivation-goal.cc @@ -1970,6 +1970,9 @@ void LocalDerivationGoal::runChild() if (rmdir("real-root") == -1) throw SysError("cannot remove real-root directory"); + // Make build root read-only, so `mkdir /homeless-shelter` would fail. + chmod_("/", 0555); + /* Switch to the sandbox uid/gid in the user namespace, which corresponds to the build user or calling user in the parent namespace. */ diff --git a/tests/functional/build.sh b/tests/functional/build.sh index 5396a465fe3..5206940af9b 100755 --- a/tests/functional/build.sh +++ b/tests/functional/build.sh @@ -152,6 +152,11 @@ nix build --impure -f multiple-outputs.nix --json e --no-link \ (.outputs | keys == ["a_a", "b"])) ' +# Make sure that `mkdir $HOME` fails with a "Permission denied" or "Operation not permitted" error +out="$(nix build -f mkdir-home-failing.nix -L 2>&1)" && status=0 || status=$? +test "$status" = 1 +<<<"$out" grepQuiet -E "Permission denied" || <<<"$out" grepQuiet -E "Operation not permitted" + # Make sure that `--stdin` works and does not apply any defaults printf "" | nix build --no-link --stdin --json | jq --exit-status '. == []' printf "%s\n" "$drv^*" | nix build --no-link --stdin --json | jq --exit-status '.[0]|has("drvPath")' diff --git a/tests/functional/mkdir-home-failing.nix b/tests/functional/mkdir-home-failing.nix new file mode 100644 index 00000000000..8f0ac39ba10 --- /dev/null +++ b/tests/functional/mkdir-home-failing.nix @@ -0,0 +1,8 @@ +with import ./config.nix; +mkDerivation { + name = "mkdir-home-no-permission"; + builder = builtins.toFile "builder.sh" + '' + mkdir $HOME + ''; +}