From 4c9ec5f1eece90929eb3b525c28f3713b7153d7d Mon Sep 17 00:00:00 2001
From: xiadanni <xiadanni1@huawei.com>
Date: Tue, 19 Jan 2021 20:34:45 +0800
Subject: [PATCH] containerd:fix potential panic for task in unknown state

Upstream:https://github.com/containerd/containerd/pull/3611

Signed-off-by: xiadanni <xiadanni1@huawei.com>
---
 cio/io_unix.go | 22 ++++++++++++----------
 container.go   | 13 +++++++++++--
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/cio/io_unix.go b/cio/io_unix.go
index 3ab2a30..53b6b2d 100644
--- a/cio/io_unix.go
+++ b/cio/io_unix.go
@@ -72,17 +72,19 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
 	}
 
 	var wg = &sync.WaitGroup{}
-	wg.Add(1)
-	go func() {
-		p := bufPool.Get().(*[]byte)
-		defer bufPool.Put(p)
-
-		io.CopyBuffer(ioset.Stdout, pipes.Stdout, *p)
-		pipes.Stdout.Close()
-		wg.Done()
-	}()
+	if fifos.Stdout != "" {
+		wg.Add(1)
+		go func() {
+			p := bufPool.Get().(*[]byte)
+			defer bufPool.Put(p)
+
+			io.CopyBuffer(ioset.Stdout, pipes.Stdout, *p)
+			pipes.Stdout.Close()
+			wg.Done()
+		}()
+	}
 
-	if !fifos.Terminal {
+	if !fifos.Terminal && fifos.Stderr != "" {
 		wg.Add(1)
 		go func() {
 			p := bufPool.Get().(*[]byte)
diff --git a/container.go b/container.go
index 3c09b2d..63b074a 100644
--- a/container.go
+++ b/container.go
@@ -25,6 +25,7 @@ import (
 
 	"github.com/containerd/containerd/api/services/tasks/v1"
 	"github.com/containerd/containerd/api/types"
+	tasktypes "github.com/containerd/containerd/api/types/task"
 	"github.com/containerd/containerd/cio"
 	"github.com/containerd/containerd/containers"
 	"github.com/containerd/containerd/errdefs"
@@ -32,6 +33,7 @@ import (
 	"github.com/containerd/typeurl"
 	prototypes "github.com/gogo/protobuf/types"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // Container is a metadata object for container resources and task creation
@@ -284,9 +286,16 @@ func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, er
 		return nil, err
 	}
 	var i cio.IO
+
 	if ioAttach != nil {
-		if i, err = attachExistingIO(response, ioAttach); err != nil {
-			return nil, err
+		if response.Process.Status == tasktypes.StatusUnknown {
+			logrus.Warnf("container %v loadTask: task get returns process status unknown", c.id)
+		} else {
+			// Do not attach IO for task in unknown state, because there
+			// are no fifo paths anyway.
+			if i, err = attachExistingIO(response, ioAttach); err != nil {
+				return nil, err
+			}
 		}
 	}
 	t := &task{
-- 
1.8.3.1

