Skip to content

Commit

Permalink
Fix segfault in builtin fetchurl
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
edolstra committed Oct 21, 2015
1 parent 133a421 commit 357d31b
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/libstore/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

#if __linux__
#include <sys/personality.h>
#include <sys/mman.h>
#endif

#if HAVE_STATVFS
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 357d31b

Please sign in to comment.