summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-08-30 15:46:12 -0700
committerShentubot <shentubot@google.com>2018-08-30 15:47:18 -0700
commit5ade9350ad18476a2cddbd3a0b36778d1c6ec376 (patch)
tree9e74ab5057b89e08a453de427ce359199014d925 /runsc/sandbox
parent8bfb5fa91977a4b10d7ad87fe4627c236f841137 (diff)
runsc: Pass log and config files to sandbox process by FD.
This is a prereq for running the sandbox process as user "nobody", when it may not have permissions to open these files. Instead, we must open then before starting the sandbox process, and pass them by FD. PiperOrigin-RevId: 210995199 Change-Id: I715875a9553290b4a49394a8fcd93be78b1933dd
Diffstat (limited to 'runsc/sandbox')
-rw-r--r--runsc/sandbox/sandbox.go74
1 files changed, 57 insertions, 17 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index f14a2f8c9..f58916574 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -233,16 +233,6 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
// starts at 3 because 0, 1, and 2 are taken by stdin/out/err.
nextFD := 3
- // Create control server socket here and donate FD to child process because
- // it may be in a different network namespace and won't be reachable from
- // outside.
- addr := boot.ControlSocketAddr(s.ID)
- fd, err := server.CreateSocket(addr)
- log.Infof("Creating sandbox process with addr: %s", addr[1:]) // skip "\00".
- if err != nil {
- return fmt.Errorf("error creating control server socket for sandbox %q: %v", s.ID, err)
- }
-
consoleEnabled := consoleSocket != ""
binPath, err := specutils.BinPath()
@@ -251,16 +241,61 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
}
cmd := exec.Command(binPath, conf.ToFlags()...)
cmd.SysProcAttr = &syscall.SysProcAttr{}
- cmd.Args = append(cmd.Args,
- "boot",
- "--bundle", bundleDir,
- "--controller-fd="+strconv.Itoa(nextFD),
- "--console="+strconv.FormatBool(consoleEnabled))
- nextFD++
- controllerFile := os.NewFile(uintptr(fd), "control_server_socket")
+ // Open the log files to pass to the sandbox as FDs.
+ //
+ // These flags must come BEFORE the "boot" command in cmd.Args.
+ if conf.LogFilename != "" {
+ logFile, err := os.OpenFile(conf.LogFilename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ return fmt.Errorf("error opening log file %q: %v", conf.LogFilename, err)
+ }
+ defer logFile.Close()
+ cmd.ExtraFiles = append(cmd.ExtraFiles, logFile)
+ cmd.Args = append(cmd.Args, "--log-fd="+strconv.Itoa(nextFD))
+ nextFD++
+ }
+ if conf.DebugLogDir != "" {
+ debugLogFile, err := specutils.DebugLogFile(conf.DebugLogDir, "boot")
+ if err != nil {
+ return fmt.Errorf("error opening debug log file in %q: %v", conf.DebugLogDir, err)
+ }
+ defer debugLogFile.Close()
+ cmd.ExtraFiles = append(cmd.ExtraFiles, debugLogFile)
+ cmd.Args = append(cmd.Args, "--debug-log-fd="+strconv.Itoa(nextFD))
+ nextFD++
+ }
+
+ // Add the "boot" command to the args.
+ //
+ // All flags after this must be for the boot command
+ cmd.Args = append(cmd.Args, "boot", "--console="+strconv.FormatBool(consoleEnabled))
+
+ // Create a socket for the control server and donate it to the sandbox.
+ addr := boot.ControlSocketAddr(s.ID)
+ sockFD, err := server.CreateSocket(addr)
+ log.Infof("Creating sandbox process with addr: %s", addr[1:]) // skip "\00".
+ if err != nil {
+ return fmt.Errorf("error creating control server socket for sandbox %q: %v", s.ID, err)
+ }
+ controllerFile := os.NewFile(uintptr(sockFD), "control_server_socket")
defer controllerFile.Close()
cmd.ExtraFiles = append(cmd.ExtraFiles, controllerFile)
+ cmd.Args = append(cmd.Args, "--controller-fd="+strconv.Itoa(nextFD))
+ nextFD++
+
+ // Open the spec file to donate to the sandbox.
+ if conf.SpecFile == "" {
+ return fmt.Errorf("conf.SpecFile must be set")
+ }
+ specFile, err := os.Open(conf.SpecFile)
+ if err != nil {
+ return fmt.Errorf("error opening spec file %q: %v", conf.SpecFile, err)
+ }
+ defer specFile.Close()
+ cmd.ExtraFiles = append(cmd.ExtraFiles, specFile)
+ cmd.Args = append(cmd.Args, "--spec-fd="+strconv.Itoa(nextFD))
+ nextFD++
// If there is a gofer, sends all socket ends to the sandbox.
for _, f := range ioFiles {
@@ -357,6 +392,11 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
nss = append(nss, specs.LinuxNamespace{Type: specs.UserNamespace})
}
+ // Log the fds we are donating to the sandbox process.
+ for i, f := range cmd.ExtraFiles {
+ log.Debugf("Donating FD %d: %q", i+3, f.Name())
+ }
+
log.Debugf("Starting sandbox: %s %v", binPath, cmd.Args)
if err := specutils.StartInNS(cmd, nss); err != nil {
return err