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

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