aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-01-24 12:05:30 +0100
committerGitHub <noreply@github.com>2022-01-24 12:05:30 +0100
commit076945c80815323658f02ef5e04a9c0e9f638d1c (patch)
treecd9e33783e1e8745d522e25309457cdbb6f6cd1f
parentc9a4ddb9c0a7d15c29d904a017d4d5d58492fdfd (diff)
parent0407436b0f15900399d11da43178cd09fddba0af (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.cc5
-rw-r--r--tests/big-derivation-attr.nix13
-rw-r--r--tests/simple.sh6
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