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 <evan@phx.io>
(cherry picked from commit 7b26da9ee3)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Evan Phoenix
2025-01-21 09:58:31 -08:00
committed by lfbzhm
parent baefcaedc7
commit e64390545e
+11 -10
View File
@@ -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.Hooks != nil {