From c2d2a0fe2db4d15ac7ad4622f7fa2bd7edc70092 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sat, 22 Nov 2025 22:34:37 +0100 Subject: [PATCH] libexpr: fix stack overflow in checkMeta on deeply nested structures --- src/libexpr/get-drvs.cc | 2 ++ tests/functional/simple.sh | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 4315f3335..2a7b90057 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -213,6 +213,8 @@ StringSet PackageInfo::queryMetaNames() bool PackageInfo::checkMeta(Value & v) { + auto _level = state->addCallDepth(v.determinePos(noPos)); + state->forceValue(v, v.determinePos(noPos)); if (v.type() == nList) { for (auto elem : v.listView()) diff --git a/tests/functional/simple.sh b/tests/functional/simple.sh index e284ec809..52304b509 100755 --- a/tests/functional/simple.sh +++ b/tests/functional/simple.sh @@ -40,3 +40,9 @@ fi # 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" + +# Test that nix-env -qa --meta on deeply nested meta attributes produces a +# controlled stack overflow error rather than a segfault. +echo 'let f = n: { type = "derivation"; name = "test"; system = "x86_64-linux"; meta.nested = f (n + 1); }; in { pkg = f 0; }' > "$TEST_ROOT/deep-meta.nix" +expectStderr 1 nix-env -qa -f "$TEST_ROOT/deep-meta.nix" --json --meta \ + | grepQuiet "stack overflow; max-call-depth exceeded"