Skip to content

Commit 5d93fed

Browse files
committed
Set init processes as non-dumpable
This sets the init processes that join and setup the container's namespaces as non-dumpable before they setns to the container's pid (or any other ) namespace. This settings is automatically reset to the default after the Exec in the container so that it does not change functionality for the applications that are running inside, just our init processes. This prevents parent processes, the pid 1 of the container, to ptrace the init process before it drops caps and other sets LSMs. This patch also ensures that the stateDirFD being used is still closed prior to exec, even though it is set as O_CLOEXEC, because of the order in the kernel. https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 The order during the exec syscall is that the process is set back to dumpable before O_CLOEXEC are processed. Signed-off-by: Michael Crosby <[email protected]>
1 parent 2cc5a91 commit 5d93fed

File tree

4 files changed

+18
-4
lines changed

4 files changed

+18
-4
lines changed

libcontainer/init_linux.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error)
7777
switch t {
7878
case initSetns:
7979
return &linuxSetnsInit{
80-
pipe: pipe,
81-
config: config,
80+
pipe: pipe,
81+
config: config,
82+
stateDirFD: stateDirFD,
8283
}, nil
8384
case initStandard:
8485
return &linuxStandardInit{

libcontainer/nsenter/nsexec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,11 @@ void nsexec(void)
424424
if (pipenum == -1)
425425
return;
426426

427+
/* make the process non-dumpable */
428+
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
429+
bail("failed to set process as non-dumpable");
430+
}
431+
427432
/* Parse all of the netlink configuration. */
428433
nl_parse(pipenum, &config);
429434

libcontainer/setns_init_linux.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package libcontainer
55
import (
66
"fmt"
77
"os"
8+
"syscall"
89

910
"github.com/opencontainers/runc/libcontainer/apparmor"
1011
"github.com/opencontainers/runc/libcontainer/keys"
@@ -16,8 +17,9 @@ import (
1617
// linuxSetnsInit performs the container's initialization for running a new process
1718
// inside an existing container.
1819
type linuxSetnsInit struct {
19-
pipe *os.File
20-
config *initConfig
20+
pipe *os.File
21+
config *initConfig
22+
stateDirFD int
2123
}
2224

2325
func (l *linuxSetnsInit) getSessionRingName() string {
@@ -58,5 +60,8 @@ func (l *linuxSetnsInit) Init() error {
5860
if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
5961
return err
6062
}
63+
// close the statedir fd before exec because the kernel resets dumpable in the wrong order
64+
// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
65+
syscall.Close(l.stateDirFD)
6166
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
6267
}

libcontainer/standard_init_linux.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ func (l *linuxStandardInit) Init() error {
179179
return newSystemErrorWithCause(err, "init seccomp")
180180
}
181181
}
182+
// close the statedir fd before exec because the kernel resets dumpable in the wrong order
183+
// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
184+
syscall.Close(l.stateDirFD)
182185
if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
183186
return newSystemErrorWithCause(err, "exec user process")
184187
}

0 commit comments

Comments
 (0)