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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user