Description
When deleting a task that was started with one of its three standard file descriptors (stdin, stdout, stderr) as /dev/null (or anything else in /dev), the entire /dev directory is wiped out.
Steps to reproduce the issue:
- Create a container
- Create a task with at least one of stdin/stdout/stderr as
/dev/null. I was unable replicate the issue when started via ctr command, but yes via code (below)
- Kill the task
ctr t kill foo
- Delete the task
ctr t delete foo
- Your entire
/dev is emptied out
io := cio.Config{
Stdin: "/dev/null",
Stdout: stdoutFile,
Stderr: stderrFile,
Terminal: false,
}
task, err := ctr.NewTask(ctx, io)
Describe the results you received:
emptied /dev
Describe the results you expected:
No collateral damage
Output of containerd --version:
$ containerd --version
containerd github.com/containerd/containerd v1.3.2-1-g49b826bf 49b826bfdf925d41764f6ed77cbe332ec56fd6c7
$ ctr --version
ctr github.com/containerd/containerd v1.3.2-1-g49b826bf
Any other relevant information:
I traced the source of the issue, and can replicate it with latest code in git. The problem specifically is here:
path := getFifoDir([]string{
response.Process.Stdin,
response.Process.Stdout,
response.Process.Stderr,
})
closer := func() error {
return os.RemoveAll(path)
}
The getFifoDir() assumes:
- all stdin/stdout/stderr are in a single directory
- that directory is dedicated to this task
Thus, upon deletion of the task, it does os.RemoveAll().
This isn't strictly true, or at least isn't so in the docs that I found; e.g. /dev/null is used, or some other existing file is used; or some file in a directory that is shared with other files.
There are several ways to fix this, but I think first of all, os.RemoveAll() should be made optional. Let the caller indicate if the fifos (and/or the directory they are in) is meant to be removed on cleanup.
cc @justincormack @rvs @rn
Description
When deleting a task that was started with one of its three standard file descriptors (stdin, stdout, stderr) as
/dev/null(or anything else in/dev), the entire/devdirectory is wiped out.Steps to reproduce the issue:
/dev/null. I was unable replicate the issue when started viactrcommand, but yes via code (below)ctr t kill fooctr t delete foo/devis emptied outDescribe the results you received:
emptied
/devDescribe the results you expected:
No collateral damage
Output of
containerd --version:Any other relevant information:
I traced the source of the issue, and can replicate it with latest code in git. The problem specifically is here:
The
getFifoDir()assumes:Thus, upon deletion of the task, it does
os.RemoveAll().This isn't strictly true, or at least isn't so in the docs that I found; e.g.
/dev/nullis used, or some other existing file is used; or some file in a directory that is shared with other files.There are several ways to fix this, but I think first of all,
os.RemoveAll()should be made optional. Let the caller indicate if the fifos (and/or the directory they are in) is meant to be removed on cleanup.cc @justincormack @rvs @rn