diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index 344906eb34fa..3635e0edba1d 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -1181,13 +1181,18 @@ substituteAllInPlace() { # the environment used for building. dumpVars() { if [ "${noDumpEnvVars:-0}" != 1 ]; then - # On darwin, install(1) cannot be called with /dev/stdin or fd from process substitution - # so first we create the file and then write to it - # See https://github.com/NixOS/nixpkgs/issues/335016 - { - install -m 0600 /dev/null "$NIX_BUILD_TOP/env-vars" && - export 2>/dev/null >| "$NIX_BUILD_TOP/env-vars" - } || true + # Don't use `install` here to prevent executing a process each time. + + # Set umask to create env-vars file with 0600 permissions (owner read/write only) + local old_umask + old_umask=$(umask) + umask 0077 + + # Dump all environment variables to the env-vars file + export 2>/dev/null > "$NIX_BUILD_TOP/env-vars" + + # Restore original umask + umask "$old_umask" fi } diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix index c961d37f409d..98fd7ebd61ef 100644 --- a/pkgs/test/stdenv/default.nix +++ b/pkgs/test/stdenv/default.nix @@ -404,6 +404,50 @@ in stdenv' = bootStdenv; }; + ensure-no-execve-in-setup-sh = + derivation { + name = "ensure-no-execve-in-setup-sh"; + system = stdenv.system; + builder = "${stdenv.bootstrapTools}/bin/bash"; + PATH = "${pkgs.strace}/bin:${stdenv.bootstrapTools}/bin"; + initialPath = [ + stdenv.bootstrapTools + pkgs.strace + ]; + args = [ + "-c" + '' + countCall() { + echo "$stats" | tr -s ' ' | grep "$1" | cut -d ' ' -f5 + } + + # prevent setup.sh from running `nproc` when cores=0 + # (this would mess up the syscall stats) + export NIX_BUILD_CORES=1 + + echo "Analyzing setup.sh with strace" + stats=$(strace -fc bash -c ". ${../../stdenv/generic/setup.sh}" 2>&1) + echo "$stats" | head -n15 + + # fail if execve calls is > 1 + stats=$(strace -fc bash -c ". ${../../stdenv/generic/setup.sh}" 2>&1) + execveCalls=$(countCall execve) + if [ "$execveCalls" -gt 1 ]; then + echo "execve calls: $execveCalls; expected: 1" + echo "ERROR: setup.sh should not launch additional processes when being sourced" + exit 1 + else + echo "setup.sh doesn't launch extra processes when sourcing, as expected" + fi + + touch $out + '' + ]; + } + // { + meta = { }; + }; + structuredAttrsByDefault = lib.recurseIntoAttrs { hooks = lib.recurseIntoAttrs ( @@ -570,6 +614,5 @@ in diff $out/json $goldenJson ''; }; - }; }