From 357d31b33962fcd19f2f05bd6ce6b8c7088a6e39 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 21 Oct 2015 14:45:56 +0200 Subject: [PATCH] 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. --- src/libstore/build.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 5674e83c9..cb14c83b3 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -74,6 +74,7 @@ #if __linux__ #include +#include #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);