In chroot builds, use a private SysV IPC namespace

This improves isolation a bit further, and it's just one extra flag in
the unshare() call.

P.S. It would be very cool to use CLONE_NEWPID (to put the builder in
a private PID namespace) as well, but that's slightly more risky since
having a builder start as PID 1 may cause problems.
This commit is contained in:
Eelco Dolstra 2012-06-23 00:51:40 -04:00
parent df716c98d2
commit 7ffa523fd1

View file

@ -1776,20 +1776,27 @@ void DerivationGoal::startBuilder()
#if CHROOT_ENABLED #if CHROOT_ENABLED
if (useChroot) { if (useChroot) {
/* Create our own mount and network namespace. This /* Set up private namespaces for the build:
means that all the bind mounts we do will only show
up in this process and its children, and will - The private mount namespace ensures that all the
disappear automatically when we're done. bind mounts we do will only show up in this
Similarly, this process will not have any network process and its children, and will disappear
interface except "lo" created below. */ automatically when we're done.
if (unshare(CLONE_NEWNS | CLONE_NEWNET) == -1)
- The private network namespace ensures that the
builder cannot talk to the outside world (or vice
versa). It only has a private loopback
interface.
- The IPC namespace prevents the builder from
communicating with outside processes using SysV
IPC mechanisms (shared memory, message queues,
semaphores). It also ensures that all IPC
objects are destroyed when the builder exits. */
if (unshare(CLONE_NEWNS | CLONE_NEWNET | CLONE_NEWIPC) == -1)
throw SysError("cannot set up a private mount namespace"); throw SysError("cannot set up a private mount namespace");
/* Initialise the loopback interface. Note that this /* Initialise the loopback interface. */
loopback device is unique to this process and its
children. Thus they won't be able to open
connections to the rest of the system, or vice
versa. */
AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)); AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP));
if (fd == -1) throw SysError("cannot open IP socket"); if (fd == -1) throw SysError("cannot open IP socket");