From 5166cee70460dbaf38fd3c5212e5d629e27bee37 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sat, 22 Nov 2025 20:32:05 +0100 Subject: [PATCH] libexpr: fix stack overflow in getDerivations on deeply nested structures nix-instantiate on deeply nested structures with recurseForDerivations (e.g., `let x = { recurseForDerivations = true; more = x; }; in x`) caused an uncontrolled OS-level stack overflow with no Nix stack trace. Fix by adding call depth tracking to getDerivations, integrating with Nix's existing max-call-depth mechanism. Now produces a controlled "stack overflow; max-call-depth exceeded" error with a proper stack trace. --- src/libexpr/get-drvs.cc | 2 ++ tests/functional/simple.sh | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index c4a2b00af..4315f3335 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -378,6 +378,8 @@ static void getDerivations( Done & done, bool ignoreAssertionFailures) { + auto _level = state.addCallDepth(vIn.determinePos(noPos)); + Value v; state.autoCallFunction(autoArgs, vIn, v); diff --git a/tests/functional/simple.sh b/tests/functional/simple.sh index c1f2eef41..e284ec809 100755 --- a/tests/functional/simple.sh +++ b/tests/functional/simple.sh @@ -35,3 +35,8 @@ if test "$outPath" != "/foo/xxiwa5zlaajv6xdjynf9yym9g319d6mn-big-derivation-attr echo "big-derivation-attr.nix hash appears broken, got $outPath. Memory corruption in large drv attr?" exit 1 fi + +# Test that nix-instantiate on a deeply nested recurseForDerivations structure +# produces a controlled stack overflow error rather than a segfault. +expectStderr 1 nix-instantiate --expr 'let x = { recurseForDerivations = true; more = x; }; in x' \ + | grepQuiet "stack overflow; max-call-depth exceeded"