diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 0171b4d9f..632d7c349 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -175,6 +175,7 @@ func startInitialization() (retErr error) { return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err) } logPipe := os.NewFile(uintptr(logFd), "logpipe") + defer logPipe.Close() logrus.SetOutput(logPipe) logrus.SetFormatter(new(logrus.JSONFormatter)) @@ -190,6 +191,7 @@ func startInitialization() (retErr error) { return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD: %w", err) } fifoFile = os.NewFile(uintptr(fifoFd), "initfifo") + defer fifoFile.Close() } var consoleSocket *os.File diff --git a/libcontainer/mount_linux.go b/libcontainer/mount_linux.go index 9d4b5dcef..06df6cbbf 100644 --- a/libcontainer/mount_linux.go +++ b/libcontainer/mount_linux.go @@ -250,7 +250,7 @@ func syscallMode(i fs.FileMode) (o uint32) { // process will need to do an old-fashioned mount(2) themselves. // // This helper is only intended to be used by goCreateMountSources. -func mountFd(nsHandles *userns.Handles, m *configs.Mount) (*mountSource, error) { +func mountFd(nsHandles *userns.Handles, m *configs.Mount) (_ *mountSource, retErr error) { if !m.IsBind() { return nil, errors.New("new mount api: only bind-mounts are supported") } @@ -261,6 +261,11 @@ func mountFd(nsHandles *userns.Handles, m *configs.Mount) (*mountSource, error) var mountFile *os.File var sourceType mountSourceType + defer func() { + if retErr != nil && mountFile != nil { + mountFile.Close() + } + }() // Ideally, we would use OPEN_TREE_CLONE for everything, because we can // be sure that the file descriptor cannot be used to escape outside of diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index fddb03408..d9c441ec5 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -70,7 +70,7 @@ type processComm struct { logPipeChild *os.File } -func newProcessComm() (*processComm, error) { +func newProcessComm() (_ *processComm, retErr error) { var ( comm processComm err error @@ -79,10 +79,24 @@ func newProcessComm() (*processComm, error) { if err != nil { return nil, fmt.Errorf("unable to create init pipe: %w", err) } + defer func() { + if retErr != nil { + comm.initSockParent.Close() + comm.initSockChild.Close() + } + }() + comm.syncSockParent, comm.syncSockChild, err = newSyncSockpair("sync") if err != nil { return nil, fmt.Errorf("unable to create sync pipe: %w", err) } + defer func() { + if retErr != nil { + comm.syncSockParent.Close() + comm.syncSockChild.Close() + } + }() + comm.logPipeParent, comm.logPipeChild, err = os.Pipe() if err != nil { return nil, fmt.Errorf("unable to create log pipe: %w", err) diff --git a/notify_socket.go b/notify_socket.go index c3eddaf85..5dd5d5007 100644 --- a/notify_socket.go +++ b/notify_socket.go @@ -175,12 +175,18 @@ func notifyHost(client *net.UnixConn, ready []byte, pid1 int) error { var errUnexpectedRead = errors.New("unexpected read from synchronization pipe") // sdNotifyBarrier performs synchronization with systemd by means of the sd_notify_barrier protocol. -func sdNotifyBarrier(client *net.UnixConn) error { +func sdNotifyBarrier(client *net.UnixConn) (retErr error) { // Create a pipe for communicating with systemd daemon. pipeR, pipeW, err := os.Pipe() if err != nil { return err } + defer func() { + if retErr != nil { + pipeW.Close() + pipeR.Close() + } + }() // Get the FD for the unix socket file to be able to use sendmsg. clientFd, err := client.File()