Blame SOURCES/0001-Set-init-processes-as-non-dumpable.patch

7dff9a
From 50a19c6ff828c58e5dab13830bd3dacde268afe5 Mon Sep 17 00:00:00 2001
7dff9a
From: Michael Crosby <crosbymichael@gmail.com>
7dff9a
Date: Wed, 7 Dec 2016 15:05:51 -0800
7dff9a
Subject: [PATCH] Set init processes as non-dumpable
7dff9a
7dff9a
This sets the init processes that join and setup the container's
7dff9a
namespaces as non-dumpable before they setns to the container's pid (or
7dff9a
any other ) namespace.
7dff9a
7dff9a
This settings is automatically reset to the default after the Exec in
7dff9a
the container so that it does not change functionality for the
7dff9a
applications that are running inside, just our init processes.
7dff9a
7dff9a
This prevents parent processes, the pid 1 of the container, to ptrace
7dff9a
the init process before it drops caps and other sets LSMs.
7dff9a
7dff9a
This patch also ensures that the stateDirFD being used is still closed
7dff9a
prior to exec, even though it is set as O_CLOEXEC, because of the order
7dff9a
in the kernel.
7dff9a
7dff9a
https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
7dff9a
7dff9a
The order during the exec syscall is that the process is set back to
7dff9a
dumpable before O_CLOEXEC are processed.
7dff9a
7dff9a
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
7dff9a
---
7dff9a
 libcontainer/init_linux.go          | 3 ++-
7dff9a
 libcontainer/nsenter/nsexec.c       | 5 +++++
7dff9a
 libcontainer/setns_init_linux.go    | 7 ++++++-
7dff9a
 libcontainer/standard_init_linux.go | 3 +++
7dff9a
 4 files changed, 16 insertions(+), 2 deletions(-)
7dff9a
7dff9a
diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go
7dff9a
index b1e6762..4043d51 100644
7dff9a
--- a/libcontainer/init_linux.go
7dff9a
+++ b/libcontainer/init_linux.go
7dff9a
@@ -77,7 +77,8 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error)
7dff9a
 	switch t {
7dff9a
 	case initSetns:
7dff9a
 		return &linuxSetnsInit{
7dff9a
-			config: config,
7dff9a
+			config:     config,
7dff9a
+			stateDirFD: stateDirFD,
7dff9a
 		}, nil
7dff9a
 	case initStandard:
7dff9a
 		return &linuxStandardInit{
7dff9a
diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c
7dff9a
index b93f827..4b5398b 100644
7dff9a
--- a/libcontainer/nsenter/nsexec.c
7dff9a
+++ b/libcontainer/nsenter/nsexec.c
7dff9a
@@ -408,6 +408,11 @@ void nsexec(void)
7dff9a
 	if (pipenum == -1)
7dff9a
 		return;
7dff9a
 
7dff9a
+	/* make the process non-dumpable */
7dff9a
+	if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
7dff9a
+		bail("failed to set process as non-dumpable");
7dff9a
+	}
7dff9a
+
7dff9a
 	/* Parse all of the netlink configuration. */
7dff9a
 	nl_parse(pipenum, &config);
7dff9a
 
7dff9a
diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go
7dff9a
index 2a8f345..7f5f182 100644
7dff9a
--- a/libcontainer/setns_init_linux.go
7dff9a
+++ b/libcontainer/setns_init_linux.go
7dff9a
@@ -5,6 +5,7 @@ package libcontainer
7dff9a
 import (
7dff9a
 	"fmt"
7dff9a
 	"os"
7dff9a
+	"syscall"
7dff9a
 
7dff9a
 	"github.com/opencontainers/runc/libcontainer/apparmor"
7dff9a
 	"github.com/opencontainers/runc/libcontainer/keys"
7dff9a
@@ -16,7 +17,8 @@ import (
7dff9a
 // linuxSetnsInit performs the container's initialization for running a new process
7dff9a
 // inside an existing container.
7dff9a
 type linuxSetnsInit struct {
7dff9a
-	config *initConfig
7dff9a
+	config     *initConfig
7dff9a
+	stateDirFD int
7dff9a
 }
7dff9a
 
7dff9a
 func (l *linuxSetnsInit) getSessionRingName() string {
7dff9a
@@ -49,5 +51,8 @@ func (l *linuxSetnsInit) Init() error {
7dff9a
 	if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
7dff9a
 		return err
7dff9a
 	}
7dff9a
+	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
7dff9a
+	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
7dff9a
+	syscall.Close(l.stateDirFD)
7dff9a
 	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
7dff9a
 }
7dff9a
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
7dff9a
index 2104f1a..6a65154 100644
7dff9a
--- a/libcontainer/standard_init_linux.go
7dff9a
+++ b/libcontainer/standard_init_linux.go
7dff9a
@@ -171,6 +171,9 @@ func (l *linuxStandardInit) Init() error {
7dff9a
 			return newSystemErrorWithCause(err, "init seccomp")
7dff9a
 		}
7dff9a
 	}
7dff9a
+	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
7dff9a
+	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
7dff9a
+	syscall.Close(l.stateDirFD)
7dff9a
 	if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
7dff9a
 		return newSystemErrorWithCause(err, "exec user process")
7dff9a
 	}
7dff9a
-- 
7dff9a
2.11.0
7dff9a