diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-02-12 14:57:58 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-02-12 18:13:30 +0100 |
commit | 2550ded989efc889da1785b07865815b7e1b9415 (patch) | |
tree | bf2964ddaed587f3653d0d75f9c37933502599cf | |
parent | e22367562515669dc05ed4d5a8980ad6c303fc02 (diff) | |
download | podman-2550ded989efc889da1785b07865815b7e1b9415.tar.gz podman-2550ded989efc889da1785b07865815b7e1b9415.tar.bz2 podman-2550ded989efc889da1785b07865815b7e1b9415.zip |
rootlessport: fix potential hang
write to the error pipe only in case of an error. Otherwise we may
end up in a race condition in the select statement below as the read
from errChan happens before initComplete and the function returns
immediately nil.
Closes: https://github.com/containers/libpod/issues/5182
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r-- | pkg/rootlessport/rootlessport_linux.go | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index 3e678d33a..acdf3198b 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -122,6 +122,7 @@ func parent() error { logrus.WithError(driverErr).Warn("parent driver exited") } errCh <- driverErr + close(errCh) }() opaque := driver.OpaqueForChild() logrus.Infof("opaque=%+v", opaque) @@ -142,7 +143,7 @@ func parent() error { }() // reexec the child process in the child netns - cmd := exec.Command(fmt.Sprintf("/proc/%d/exe", os.Getpid())) + cmd := exec.Command("/proc/self/exe") cmd.Args = []string{reexecChildKey} cmd.Stdin = childQuitR cmd.Stdout = &logrusWriter{prefix: "child"} @@ -164,12 +165,19 @@ func parent() error { logrus.Info("waiting for initComplete") // wait for the child to connect to the parent - select { - case <-initComplete: - logrus.Infof("initComplete is closed; parent and child established the communication channel") - case err := <-errCh: - return err +outer: + for { + select { + case <-initComplete: + logrus.Infof("initComplete is closed; parent and child established the communication channel") + break outer + case err := <-errCh: + if err != nil { + return err + } + } } + defer func() { logrus.Info("stopping parent driver") quit <- struct{}{} |