diff options
author | Giuseppe Scrivano <giuseppe@scrivano.org> | 2020-09-25 16:27:14 +0200 |
---|---|---|
committer | Giuseppe Scrivano <giuseppe@scrivano.org> | 2020-09-25 18:08:46 +0200 |
commit | 7147c935aa29dca2f89083bfbe2c058a0ca69857 (patch) | |
tree | dc79a7522b73e5d048424e860d3d8969aaec4b03 | |
parent | 08cc91926db1cd17509f8578e2ff00a94747dbd4 (diff) | |
download | podman-7147c935aa29dca2f89083bfbe2c058a0ca69857.tar.gz podman-7147c935aa29dca2f89083bfbe2c058a0ca69857.tar.bz2 podman-7147c935aa29dca2f89083bfbe2c058a0ca69857.zip |
rootless: fix hang when newidmap is not installed
when newidmap is not installed the code would hit the
reexec_in_user_namespace_wait code and wait for the child process to
be terminated. The child process is blocked waiting on the w pipe.
So make sure to unblock the child process first and then clean it up.
Closes: https://github.com/containers/podman/issues/7776
Signed-off-by: Giuseppe Scrivano <giuseppe@scrivano.org>
-rw-r--r-- | pkg/rootless/rootless_linux.go | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index bbd797817..3025825db 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -216,6 +216,8 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo } r, w := os.NewFile(uintptr(fds[0]), "sync host"), os.NewFile(uintptr(fds[1]), "sync child") + var pid int + defer errorhandling.CloseQuiet(r) defer errorhandling.CloseQuiet(w) defer func() { @@ -226,18 +228,19 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo if _, err := w.Write(toWrite); err != nil { logrus.Errorf("failed to write byte 0: %q", err) } + if retErr != nil && pid > 0 { + if err := unix.Kill(pid, unix.SIGKILL); err != nil { + logrus.Errorf("failed to kill %d", pid) + } + C.reexec_in_user_namespace_wait(C.int(pid), 0) + } }() pidC := C.reexec_in_user_namespace(C.int(r.Fd()), cPausePid, cFileToRead, fileOutputFD) - pid := int(pidC) + pid = int(pidC) if pid < 0 { return false, -1, errors.Errorf("cannot re-exec process") } - defer func() { - if retErr != nil { - C.reexec_in_user_namespace_wait(pidC, 0) - } - }() uids, gids, err := GetConfiguredMappings() if err != nil { |