diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 01f32f506..9d5f06802 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -77,8 +77,9 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error) switch t { case initSetns: return &linuxSetnsInit{ - pipe: pipe, - config: config, + pipe: pipe, + config: config, + stateDirFD: stateDirFD, }, nil case initStandard: return &linuxStandardInit{ diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c index 5c6b95e1a..7d15aeb5a 100644 --- a/libcontainer/nsenter/nsexec.c +++ b/libcontainer/nsenter/nsexec.c @@ -424,6 +424,11 @@ void nsexec(void) if (pipenum == -1) return; + /* make the process non-dumpable */ + if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) { + bail("failed to set process as non-dumpable"); + } + /* Parse all of the netlink configuration. */ nl_parse(pipenum, &config); diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index 2e80450d6..372dfd357 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -5,6 +5,7 @@ package libcontainer import ( "fmt" "os" + "syscall" "github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/keys" @@ -16,8 +17,9 @@ import ( // linuxSetnsInit performs the container's initialization for running a new process // inside an existing container. type linuxSetnsInit struct { - pipe *os.File - config *initConfig + pipe *os.File + config *initConfig + stateDirFD int } func (l *linuxSetnsInit) getSessionRingName() string { @@ -58,5 +60,8 @@ func (l *linuxSetnsInit) Init() error { if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil { return err } + // close the statedir fd before exec because the kernel resets dumpable in the wrong order + // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 + syscall.Close(l.stateDirFD) return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) } diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 588077b5d..7b68458e6 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -179,6 +179,9 @@ func (l *linuxStandardInit) Init() error { return newSystemErrorWithCause(err, "init seccomp") } } + // close the statedir fd before exec because the kernel resets dumpable in the wrong order + // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 + syscall.Close(l.stateDirFD) if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { return newSystemErrorWithCause(err, "exec user process") }