about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-21T12·45+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-21T13·14+0200
commit357d31b33962fcd19f2f05bd6ce6b8c7088a6e39 (patch)
tree26119b3cf98b9c762d1f55f632a16218c4c16e80
parent133a421bb40cca3a74c93b05f3abe310110c6258 (diff)
Fix segfault in builtin fetchurl
The stack allocated for the builder was way too small (32 KB). This is
sufficient for normal derivations, because they just do some setup and
then exec() the actual builder. But for the fetchurl builtin
derivation it's not enough. Also, allocating the stack on the caller's
stack was fishy business.
-rw-r--r--src/libstore/build.cc10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 5674e83c9e66..cb14c83b3a98 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -74,6 +74,7 @@
 
 #if __linux__
 #include <sys/personality.h>
+#include <sys/mman.h>
 #endif
 
 #if HAVE_STATVFS
@@ -2128,14 +2129,17 @@ void DerivationGoal::startBuilder()
         ProcessOptions options;
         options.allowVfork = false;
         Pid helper = startProcess([&]() {
-            char stack[32 * 1024];
+            size_t stackSize = 1 * 1024 * 1024;
+            char * stack = (char *) mmap(0, stackSize,
+                PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
+            if (!stack) throw SysError("allocating stack");
             int flags = CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD;
             if (!fixedOutput) flags |= CLONE_NEWNET;
-            pid_t child = clone(childEntry, stack + sizeof(stack) - 8, flags, this);
+            pid_t child = clone(childEntry, stack + stackSize, flags, this);
             if (child == -1 && errno == EINVAL)
                 /* Fallback for Linux < 2.13 where CLONE_NEWPID and
                    CLONE_PARENT are not allowed together. */
-                child = clone(childEntry, stack + sizeof(stack) - 8, flags & ~CLONE_NEWPID, this);
+                child = clone(childEntry, stack + stackSize, flags & ~CLONE_NEWPID, this);
             if (child == -1) throw SysError("cloning builder process");
             writeFull(builderOut.writeSide, int2String(child) + "\n");
             _exit(0);