summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox
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/sandbox
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/sandbox')
-rw-r--r--runsc/sandbox/BUILD3
-rw-r--r--runsc/sandbox/console.go60
-rw-r--r--runsc/sandbox/sandbox.go20
3 files changed, 12 insertions, 71 deletions
diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD
index d26a4dac6..e9a39f797 100644
--- a/runsc/sandbox/BUILD
+++ b/runsc/sandbox/BUILD
@@ -5,7 +5,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "sandbox",
srcs = [
- "console.go",
"namespace.go",
"network.go",
"sandbox.go",
@@ -21,9 +20,9 @@ go_library(
"//pkg/sentry/control",
"//pkg/urpc",
"//runsc/boot",
+ "//runsc/console",
"//runsc/fsgofer",
"//runsc/specutils",
- "@com_github_kr_pty//:go_default_library",
"@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
"@com_github_vishvananda_netlink//:go_default_library",
"@org_golang_x_sys//unix:go_default_library",
diff --git a/runsc/sandbox/console.go b/runsc/sandbox/console.go
deleted file mode 100644
index 3f133e12a..000000000
--- a/runsc/sandbox/console.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package sandbox
-
-import (
- "fmt"
- "net"
- "os"
-
- "github.com/kr/pty"
- "golang.org/x/sys/unix"
-)
-
-// setupConsole creates pty master/slave pair, sends the master FD over the
-// given socket, and returns the slave.
-func setupConsole(socketPath string) (*os.File, error) {
- // Create a new pty master and slave.
- ptyMaster, ptySlave, err := pty.Open()
- if err != nil {
- return nil, fmt.Errorf("error opening pty: %v", err)
- }
- defer ptyMaster.Close()
-
- // Get a connection to the socket path.
- conn, err := net.Dial("unix", socketPath)
- if err != nil {
- ptySlave.Close()
- return nil, fmt.Errorf("error dial socket %q: %v", socketPath, err)
- }
- uc, ok := conn.(*net.UnixConn)
- if !ok {
- ptySlave.Close()
- return nil, fmt.Errorf("connection is not a UnixConn: %T", conn)
- }
- socket, err := uc.File()
- if err != nil {
- ptySlave.Close()
- return nil, fmt.Errorf("error getting file for unix socket %v: %v", uc, err)
- }
-
- // Send the master FD over the connection.
- msg := unix.UnixRights(int(ptyMaster.Fd()))
- if err := unix.Sendmsg(int(socket.Fd()), []byte("pty-master"), msg, nil, 0); err != nil {
- ptySlave.Close()
- return nil, fmt.Errorf("error sending console over unix socket %q: %v", socketPath, err)
- }
- return ptySlave, nil
-}
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index 7789608f8..e54ba4ba3 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -31,6 +31,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/control"
"gvisor.googlesource.com/gvisor/pkg/urpc"
"gvisor.googlesource.com/gvisor/runsc/boot"
+ "gvisor.googlesource.com/gvisor/runsc/console"
"gvisor.googlesource.com/gvisor/runsc/fsgofer"
"gvisor.googlesource.com/gvisor/runsc/specutils"
)
@@ -392,7 +393,7 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
"boot",
"--bundle", bundleDir,
"--controller-fd="+strconv.Itoa(nextFD),
- fmt.Sprintf("--console=%t", consoleEnabled))
+ "--console="+strconv.FormatBool(consoleEnabled))
nextFD++
controllerFile := os.NewFile(uintptr(fd), "control_server_socket")
@@ -407,14 +408,19 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
nextFD++
}
+ // Sandbox 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 consoleEnabled {
- // setupConsole will send the master on the socket, and return
- // the slave.
- tty, err := setupConsole(consoleSocket)
+ // console.NewWithSocket will send the master on the socket,
+ // and return the slave.
+ tty, err := console.NewWithSocket(consoleSocket)
if err != nil {
- return fmt.Errorf("error setting up control socket %q: %v", consoleSocket, err)
+ return fmt.Errorf("error setting up console with socket %q: %v", consoleSocket, err)
}
defer tty.Close()
@@ -423,10 +429,6 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
cmd.Stderr = tty
cmd.SysProcAttr.Setctty = true
cmd.SysProcAttr.Ctty = int(tty.Fd())
- } else {
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
}
// Detach from this session, otherwise cmd will get SIGHUP and SIGCONT