diff --git a/tty.go b/tty.go index c919d417d..284ed449b 100644 --- a/tty.go +++ b/tty.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "syscall" "github.com/docker/docker/pkg/term" "github.com/opencontainers/runc/libcontainer" @@ -18,34 +19,45 @@ func newTty(create bool, p *libcontainer.Process, rootuid int) (*tty, error) { if create { return createTty(p, rootuid) } - return createStdioPipes(p) + return createStdioPipes(p, rootuid) } // setup standard pipes so that the TTY of the calling runc process // is not inherited by the container. -func createStdioPipes(p *libcontainer.Process) (*tty, error) { - t := &tty{} +func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) { + var ( + t = &tty{} + fds []int + ) r, w, err := os.Pipe() if err != nil { return nil, err } + fds = append(fds, int(r.Fd()), int(w.Fd())) go io.Copy(w, os.Stdin) t.closers = append(t.closers, w) p.Stdin = r if r, w, err = os.Pipe(); err != nil { return nil, err } + fds = append(fds, int(r.Fd()), int(w.Fd())) go io.Copy(os.Stdout, r) p.Stdout = w t.closers = append(t.closers, r) if r, w, err = os.Pipe(); err != nil { return nil, err } + fds = append(fds, int(r.Fd()), int(w.Fd())) go io.Copy(os.Stderr, r) p.Stderr = w t.closers = append(t.closers, r) + // change the ownership of the pipe fds incase we are in a user namespace. + for _, fd := range fds { + if err := syscall.Fchown(fd, rootuid, rootuid); err != nil { + return nil, err + } + } return t, nil - } func createTty(p *libcontainer.Process, rootuid int) (*tty, error) {