diff options
author | Andrei Vagin <avagin@google.com> | 2019-01-14 14:07:05 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-01-14 14:08:19 -0800 |
commit | a46b6d453d198b96949342a81750114bfa5a5429 (patch) | |
tree | 71c32eae0ee72b46576226b0266ed63e0bf93463 /runsc/cmd/boot.go | |
parent | 7182b9cf52087bc354104ad2a23fcf4c468ab20e (diff) |
runsc: set up a minimal chroot from the sandbox process
In this case, new mounts are not created in the host mount namspaces, so
tearDownChroot isn't needed, because chroot will be destroyed with a
sandbox mount namespace.
In additional, pivot_root can't be called instead of chroot.
PiperOrigin-RevId: 229250871
Change-Id: I765bdb587d0b8287a6a8efda8747639d37c7e7b6
Diffstat (limited to 'runsc/cmd/boot.go')
-rw-r--r-- | runsc/cmd/boot.go | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index bb3435284..7ca2744bd 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -60,6 +60,9 @@ type Boot struct { // to the process. applyCaps bool + // setUpChroot is set to true if the sandbox is started in an empty root. + setUpRoot bool + // cpuNum number of CPUs to create inside the sandbox. cpuNum int @@ -99,6 +102,7 @@ func (b *Boot) SetFlags(f *flag.FlagSet) { f.Var(&b.stdioFDs, "stdio-fds", "list of FDs containing sandbox stdin, stdout, and stderr in that order") f.BoolVar(&b.console, "console", false, "set to true if the sandbox should allow terminal ioctl(2) syscalls") f.BoolVar(&b.applyCaps, "apply-caps", false, "if true, apply capabilities defined in the spec to the process") + f.BoolVar(&b.setUpRoot, "setup-root", false, "if true, set up an empty root for the process") f.IntVar(&b.cpuNum, "cpu-num", 0, "number of CPUs to create inside the sandbox") f.Uint64Var(&b.totalMem, "total-memory", 0, "sets the initial amount of total memory to report back to the container") f.IntVar(&b.userLogFD, "user-log-fd", 0, "file descriptor to write user logs to. 0 means no logging.") @@ -116,6 +120,31 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Ensure that if there is a panic, all goroutine stacks are printed. debug.SetTraceback("all") + if b.setUpRoot { + if err := setUpChroot(); err != nil { + Fatalf("error setting up chroot: %v", err) + } + + specutils.ExePath = "/runsc" + if !b.applyCaps { + // Remove --setup-root arg to call myself. + var args []string + for _, arg := range os.Args { + if !strings.Contains(arg, "setup-root") { + args = append(args, arg) + } + } + // Note that we've already read the spec from the spec FD, and + // we will read it again after the exec call. This works + // because the ReadSpecFromFile function seeks to the beginning + // of the file before reading. + if err := callSelfAsNobody(args); err != nil { + Fatalf("%v", err) + } + panic("callSelfAsNobody must never return success") + } + } + // Get the spec from the specFD. specFile := os.NewFile(uintptr(b.specFD), "spec file") defer specFile.Close() @@ -144,7 +173,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Remove --apply-caps arg to call myself. var args []string for _, arg := range os.Args { - if !strings.Contains(arg, "apply-caps") { + if !strings.Contains(arg, "setup-root") && !strings.Contains(arg, "apply-caps") { args = append(args, arg) } } |