Skip to content

Commit

Permalink
Merge pull request #2802 from kolyshkin/run-leaks
Browse files Browse the repository at this point in the history
libct: fix some container.Run fd leaks, add fd leak test
  • Loading branch information
AkihiroSuda authored Mar 31, 2021
2 parents b79201f + 79a8647 commit a1270a6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
7 changes: 5 additions & 2 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type linuxContainer struct {
criuVersion int
state containerState
created time.Time
fifo *os.File
}

// State represents a running container's state
Expand Down Expand Up @@ -380,6 +381,7 @@ func (c *linuxContainer) start(process *Process) (retErr error) {
}

if process.Init {
c.fifo.Close()
if c.config.Hooks != nil {
s, err := c.currentOCIState()
if err != nil {
Expand Down Expand Up @@ -455,12 +457,13 @@ func (c *linuxContainer) deleteExecFifo() {
// fd, with _LIBCONTAINER_FIFOFD set to its fd number.
func (c *linuxContainer) includeExecFifo(cmd *exec.Cmd) error {
fifoName := filepath.Join(c.root, execFifoFilename)
fifoFd, err := unix.Open(fifoName, unix.O_PATH|unix.O_CLOEXEC, 0)
fifo, err := os.OpenFile(fifoName, unix.O_PATH|unix.O_CLOEXEC, 0)
if err != nil {
return err
}
c.fifo = fifo

cmd.ExtraFiles = append(cmd.ExtraFiles, os.NewFile(uintptr(fifoFd), fifoName))
cmd.ExtraFiles = append(cmd.ExtraFiles, fifo)
cmd.Env = append(cmd.Env,
"_LIBCONTAINER_FIFOFD="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1))
return nil
Expand Down
61 changes: 61 additions & 0 deletions libcontainer/integration/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1996,3 +1996,64 @@ func TestCGROUPHost(t *testing.T) {
t.Fatalf("cgroup link not equal to host link %q %q", actual, l)
}
}

func TestFdLeaks(t *testing.T) {
if testing.Short() {
return
}

rootfs, err := newRootfs()
ok(t, err)
defer remove(rootfs)

pfd, err := os.Open("/proc/self/fd")
ok(t, err)
defer pfd.Close()
fds0, err := pfd.Readdirnames(0)
ok(t, err)
_, err = pfd.Seek(0, 0)
ok(t, err)

config := newTemplateConfig(&tParam{rootfs: rootfs})
buffers, exitCode, err := runContainer(config, "", "true")
ok(t, err)

if exitCode != 0 {
t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
}

fds1, err := pfd.Readdirnames(0)
ok(t, err)

if len(fds1) == len(fds0) {
return
}
// Show the extra opened files.

excludedPaths := []string{
"/sys/fs/cgroup", // opened once, see prepareOpenat2
"anon_inode:bpf-prog", // FIXME: see https://github.com/opencontainers/runc/issues/2366#issuecomment-776411392
}

count := 0
next_fd:
for _, fd1 := range fds1 {
for _, fd0 := range fds0 {
if fd0 == fd1 {
continue next_fd
}
}
dst, _ := os.Readlink("/proc/self/fd/" + fd1)
for _, ex := range excludedPaths {
if ex == dst {
continue next_fd
}
}

count++
t.Logf("extra fd %s -> %s", fd1, dst)
}
if count > 0 {
t.Fatalf("found %d extra fds after container.Run", count)
}
}

0 comments on commit a1270a6

Please sign in to comment.