From 3f0e2367c222fe362031f806f002fb8a62be6360 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 17 May 2018 10:42:26 +0200 Subject: libpod: fix panic when using -t and the process fails to start We were closing resize both on the receiver and the sender side. This was racy as the sender might have written to a closed channel. If the container could not be created, the attach exited immediately causing the channel to be closed before the write from resizeTty. Change the logic to close only from the senderSide and add another channel to notify the resizeTty goroutine when the container exited. Closes: https://github.com/projectatomic/libpod/issues/785 Signed-off-by: Giuseppe Scrivano Closes: #787 Approved by: mheon --- cmd/podman/utils.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index 48b30d274..227426c18 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -25,7 +25,12 @@ func attachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys if haveTerminal && ctr.Spec().Process.Terminal { logrus.Debugf("Handling terminal attach") - resizeTty(resize) + resizeTerminate := make(chan interface{}) + defer func() { + resizeTerminate <- true + close(resizeTerminate) + }() + resizeTty(resize, resizeTerminate) oldTermState, err := term.SaveState(os.Stdin.Fd()) if err != nil { @@ -76,7 +81,12 @@ func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detac if haveTerminal && ctr.Spec().Process.Terminal { logrus.Debugf("Handling terminal attach") - resizeTty(resize) + resizeTerminate := make(chan interface{}) + defer func() { + resizeTerminate <- true + close(resizeTerminate) + }() + resizeTty(resize, resizeTerminate) oldTermState, err := term.SaveState(os.Stdin.Fd()) if err != nil { @@ -131,7 +141,7 @@ func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detac } // Helper for prepareAttach - set up a goroutine to generate terminal resize events -func resizeTty(resize chan remotecommand.TerminalSize) { +func resizeTty(resize chan remotecommand.TerminalSize, resizeTerminate chan interface{}) { sigchan := make(chan os.Signal, 1) gosignal.Notify(sigchan, signal.SIGWINCH) sendUpdate := func() { @@ -150,8 +160,14 @@ func resizeTty(resize chan remotecommand.TerminalSize) { // Update the terminal size immediately without waiting // for a SIGWINCH to get the correct initial size. sendUpdate() - for range sigchan { - sendUpdate() + for { + select { + case <-resizeTerminate: + return + + case <-sigchan: + sendUpdate() + } } }() } -- cgit v1.2.3-54-g00ecf