From dd569d89133b9157011be854d1f3af0d8ca6c3b5 Mon Sep 17 00:00:00 2001 From: Randy Eckenrode Date: Sun, 22 Sep 2024 18:44:26 -0400 Subject: [PATCH] xcbuild: avoid `xcrun` invoking itself via `/usr/bin` stubs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS ships with several stubs in `/usr/bin` that invoke `xcrun` to run the tools from the active SDK. When `/usr/bin` is in `PATH`, this will cause `xcrun` from xcbuild to invoke itself over and over. Filtering `/usr/bin` from `xcrun`’s search path prevents this from happening. --- pkgs/by-name/xc/xcbuild/package.nix | 2 + ...ork-bomb-when-searching-system-paths.patch | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 pkgs/by-name/xc/xcbuild/patches/Avoid-fork-bomb-when-searching-system-paths.patch diff --git a/pkgs/by-name/xc/xcbuild/package.nix b/pkgs/by-name/xc/xcbuild/package.nix index 46db53105337..f08cf4328576 100644 --- a/pkgs/by-name/xc/xcbuild/package.nix +++ b/pkgs/by-name/xc/xcbuild/package.nix @@ -84,6 +84,8 @@ stdenv.mkDerivation (finalAttrs: { patches = [ # Add missing header for `abort` ./patches/includes.patch + # Prevent xcrun from recursively invoking itself + ./patches/Avoid-fork-bomb-when-searching-system-paths.patch ]; prePatch = '' diff --git a/pkgs/by-name/xc/xcbuild/patches/Avoid-fork-bomb-when-searching-system-paths.patch b/pkgs/by-name/xc/xcbuild/patches/Avoid-fork-bomb-when-searching-system-paths.patch new file mode 100644 index 000000000000..bad8621e4b8c --- /dev/null +++ b/pkgs/by-name/xc/xcbuild/patches/Avoid-fork-bomb-when-searching-system-paths.patch @@ -0,0 +1,47 @@ +diff --git a/Libraries/xcsdk/Tools/xcrun.cpp b/Libraries/xcsdk/Tools/xcrun.cpp +index 9d6d4576d7..7400267c2b 100644 +--- a/Libraries/xcsdk/Tools/xcrun.cpp ++++ b/Libraries/xcsdk/Tools/xcrun.cpp +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + using libutil::DefaultFilesystem; + using libutil::Filesystem; + using libutil::FSUtil; +@@ -398,6 +400,8 @@ + fprintf(stderr, "\n"); + } + ++ std::unordered_map environment = processContext->environmentVariables(); ++ + /* + * Collect search paths for the tool. + * Can be in toolchains, target (if one is provided), developer root, +@@ -408,6 +412,15 @@ + executablePaths.insert(executablePaths.end(), defaultExecutablePaths.begin(), defaultExecutablePaths.end()); + + /* ++ * Don’t look for tools in `/usr/bin` because it can cause an infinite recursion when `xcrun` finds a shim ++ * that tries to invoke `xcrun` to run the tool. ++ */ ++ executablePaths.erase( ++ std::remove(executablePaths.begin(), executablePaths.end(), "/usr/bin"), ++ executablePaths.end() ++ ); ++ ++ /* + * Find the tool to execute. + */ + ext::optional executable = filesystem->findExecutable(*options.tool(), executablePaths); +@@ -428,8 +441,6 @@ + } else { + /* Run is the default. */ + +- std::unordered_map environment = processContext->environmentVariables(); +- + if (target != nullptr) { + /* + * Update effective environment to include the target path.