diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-01-24 12:05:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-24 12:05:30 +0100 |
commit | 076945c80815323658f02ef5e04a9c0e9f638d1c (patch) | |
tree | cd9e33783e1e8745d522e25309457cdbb6f6cd1f | |
parent | c9a4ddb9c0a7d15c29d904a017d4d5d58492fdfd (diff) | |
parent | 0407436b0f15900399d11da43178cd09fddba0af (diff) |
Merge pull request #5875 from hercules-ci/fix-large-drv-field-stack-overflow
Fix segfault or stack overflow caused by large derivation fields
-rw-r--r-- | src/libstore/derivations.cc | 5 | ||||
-rw-r--r-- | tests/big-derivation-attr.nix | 13 | ||||
-rw-r--r-- | tests/simple.sh | 6 |
3 files changed, 23 insertions, 1 deletions
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index b926bb711..3e3d50144 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -4,6 +4,7 @@ #include "util.hh" #include "worker-protocol.hh" #include "fs-accessor.hh" +#include <boost/container/small_vector.hpp> namespace nix { @@ -272,7 +273,9 @@ Derivation parseDerivation(const Store & store, std::string && s, std::string_vi static void printString(string & res, std::string_view s) { - char buf[s.size() * 2 + 2]; + boost::container::small_vector<char, 64 * 1024> buffer; + buffer.reserve(s.size() * 2 + 2); + char * buf = buffer.data(); char * p = buf; *p++ = '"'; for (auto c : s) diff --git a/tests/big-derivation-attr.nix b/tests/big-derivation-attr.nix new file mode 100644 index 000000000..35c1187f6 --- /dev/null +++ b/tests/big-derivation-attr.nix @@ -0,0 +1,13 @@ +let + sixteenBytes = "0123456789abcdef"; + times16 = s: builtins.concatStringsSep "" [s s s s s s s s s s s s s s s s]; + exp = n: x: if n == 1 then x else times16 (exp (n - 1) x); + sixteenMegabyte = exp 6 sixteenBytes; +in +assert builtins.stringLength sixteenMegabyte == 16777216; +derivation { + name = "big-derivation-attr"; + builder = "/x"; + system = "y"; + bigAttr = sixteenMegabyte; +} diff --git a/tests/simple.sh b/tests/simple.sh index 15bd2bd16..50d44f93f 100644 --- a/tests/simple.sh +++ b/tests/simple.sh @@ -25,3 +25,9 @@ if test "$outPath" != "/foo/lfy1s6ca46rm5r6w4gg9hc0axiakjcnm-dependencies.drv"; echo "hashDerivationModulo appears broken, got $outPath" exit 1 fi + +outPath="$(NIX_REMOTE=local?store=/foo\&real=$TEST_ROOT/real-store nix-instantiate --readonly-mode big-derivation-attr.nix)" +if test "$outPath" != "/foo/xxiwa5zlaajv6xdjynf9yym9g319d6mn-big-derivation-attr.drv"; then + echo "big-derivation-attr.nix hash appears broken, got $outPath. Memory corruption in large drv attr?" + exit 1 +fi |