From 7b26da9ee3abf274ac90b7bedcbf11c3df43127a Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Tue, 21 Jan 2025 09:58:31 -0800 Subject: [PATCH] libcontainer: Prevent startup hang when CloseExecFrom errors The previous logic caused runc to hang if CloseExecFrom returned an error, as the defer waiting on logsDone never finished as the parent process was never started (and it controls the closing of logsDone via it's logsPipe). This moves the defer to after we have started the parent, with means all the logic related to managing the logsPipe should also be running. Signed-off-by: Evan Phoenix --- libcontainer/container_linux.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index c99c8a6eea5..2de3382f6a0 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -324,16 +324,6 @@ func (c *Container) start(process *Process) (retErr error) { defer process.closeClonedExes() logsDone := parent.forwardChildLogs() - if logsDone != nil { - defer func() { - // Wait for log forwarder to finish. This depends on - // runc init closing the _LIBCONTAINER_LOGPIPE log fd. - err := <-logsDone - if err != nil && retErr == nil { - retErr = fmt.Errorf("unable to forward init logs: %w", err) - } - }() - } // Before starting "runc init", mark all non-stdio open files as O_CLOEXEC // to make sure we don't leak any files into "runc init". Any files to be @@ -348,6 +338,17 @@ func (c *Container) start(process *Process) (retErr error) { return fmt.Errorf("unable to start container process: %w", err) } + if logsDone != nil { + defer func() { + // Wait for log forwarder to finish. This depends on + // runc init closing the _LIBCONTAINER_LOGPIPE log fd. + err := <-logsDone + if err != nil && retErr == nil { + retErr = fmt.Errorf("unable to forward init logs: %w", err) + } + }() + } + if process.Init { c.fifo.Close() if c.config.HasHook(configs.Poststart) {