summaryrefslogtreecommitdiffhomepage
path: root/runsc/cmd/exec.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-08-24 17:42:30 -0700
committerShentubot <shentubot@google.com>2018-08-24 17:43:21 -0700
commit106de2182d34197d76fb68863cd4a102ebac2dbb (patch)
tree9f3bce620feedb1c7f757c079157538c33b94a5a /runsc/cmd/exec.go
parentc48708a041fcc9749e0162a7708f32e5a3d7e526 (diff)
runsc: Terminal support for "docker exec -ti".
This CL adds terminal support for "docker exec". We previously only supported consoles for the container process, but not exec processes. The SYS_IOCTL syscall was added to the default seccomp filter list, but only for ioctls that get/set winsize and termios structs. We need to allow these ioctl for all containers because it's possible to run "exec -ti" on a container that was started without an attached console, after the filters have been installed. Note that control-character signals are still not properly supported. Tested with: $ docker run --runtime=runsc -it alpine In another terminial: $ docker exec -it <containerid> /bin/sh PiperOrigin-RevId: 210185456 Change-Id: I6d2401e53a7697bb988c120a8961505c335f96d9
Diffstat (limited to 'runsc/cmd/exec.go')
-rw-r--r--runsc/cmd/exec.go39
1 files changed, 36 insertions, 3 deletions
diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go
index 4ee370656..b84a80119 100644
--- a/runsc/cmd/exec.go
+++ b/runsc/cmd/exec.go
@@ -35,6 +35,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
"gvisor.googlesource.com/gvisor/pkg/urpc"
"gvisor.googlesource.com/gvisor/runsc/boot"
+ "gvisor.googlesource.com/gvisor/runsc/console"
"gvisor.googlesource.com/gvisor/runsc/container"
"gvisor.googlesource.com/gvisor/runsc/specutils"
)
@@ -50,6 +51,11 @@ type Exec struct {
detach bool
processPath string
pidFile string
+
+ // consoleSocket is the path to an AF_UNIX socket which will receive a
+ // file descriptor referencing the master end of the console's
+ // pseudoterminal.
+ consoleSocket string
}
// Name implements subcommands.Command.Name.
@@ -91,6 +97,7 @@ func (ex *Exec) SetFlags(f *flag.FlagSet) {
f.BoolVar(&ex.detach, "detach", false, "detach from the container's process")
f.StringVar(&ex.processPath, "process", "", "path to the process.json")
f.StringVar(&ex.pidFile, "pid-file", "", "filename that the container pid will be written to")
+ f.StringVar(&ex.consoleSocket, "console-socket", "", "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal")
}
// Execute implements subcommands.Command.Execute. It starts a process in an
@@ -178,11 +185,35 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
args = append(args, a)
}
}
-
cmd := exec.Command(binPath, args...)
+
+ // Exec stdio defaults to current process stdio.
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+
+ // If the console control socket file is provided, then create a new
+ // pty master/slave pair and set the tty on the sandbox process.
+ if ex.consoleSocket != "" {
+ // Create a new tty pair and send the master on the provided
+ // socket.
+ tty, err := console.NewWithSocket(ex.consoleSocket)
+ if err != nil {
+ Fatalf("error setting up console with socket %q: %v", ex.consoleSocket, err)
+ }
+ defer tty.Close()
+
+ // Set stdio to the new tty slave.
+ cmd.Stdin = tty
+ cmd.Stdout = tty
+ cmd.Stderr = tty
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Setsid: true,
+ Setctty: true,
+ Ctty: int(tty.Fd()),
+ }
+ }
+
if err := cmd.Start(); err != nil {
Fatalf("failure to start child exec process, err: %v", err)
}
@@ -252,11 +283,12 @@ func (ex *Exec) argsFromCLI(argv []string) (*control.ExecArgs, error) {
return &control.ExecArgs{
Argv: argv,
WorkingDirectory: ex.cwd,
- FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
KUID: ex.user.kuid,
KGID: ex.user.kgid,
ExtraKGIDs: extraKGIDs,
Capabilities: caps,
+ StdioIsPty: ex.consoleSocket != "",
+ FilePayload: urpc.FilePayload{[]*os.File{os.Stdin, os.Stdout, os.Stderr}},
}, nil
}
@@ -292,11 +324,12 @@ func argsFromProcess(p *specs.Process) (*control.ExecArgs, error) {
Argv: p.Args,
Envv: p.Env,
WorkingDirectory: p.Cwd,
- FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
KUID: auth.KUID(p.User.UID),
KGID: auth.KGID(p.User.GID),
ExtraKGIDs: extraKGIDs,
Capabilities: caps,
+ StdioIsPty: p.Terminal,
+ FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
}, nil
}