From 3f0e2367c222fe362031f806f002fb8a62be6360 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
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 <gscrivan@redhat.com>

Closes: #787
Approved by: mheon
---
 cmd/podman/utils.go | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

(limited to 'cmd')

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