|
|
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 |
|