diff options
Diffstat (limited to 'runsc/boot/fds.go')
-rw-r--r-- | runsc/boot/fds.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go new file mode 100644 index 000000000..4e428b49c --- /dev/null +++ b/runsc/boot/fds.go @@ -0,0 +1,89 @@ +// Copyright 2018 The gVisor Authors. +// +// 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 boot + +import ( + "fmt" + + "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/host" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + "gvisor.googlesource.com/gvisor/pkg/sentry/limits" +) + +// createFDMap creates an FD map that contains stdin, stdout, and stderr. If +// console is true, then ioctl calls will be passed through to the host FD. +// Upon success, createFDMap dups then closes stdioFDs. +func createFDMap(ctx context.Context, k *kernel.Kernel, l *limits.LimitSet, console bool, stdioFDs []int) (*kernel.FDMap, error) { + if len(stdioFDs) != 3 { + return nil, fmt.Errorf("stdioFDs should contain exactly 3 FDs (stdin, stdout, and stderr), but %d FDs received", len(stdioFDs)) + } + + fdm := k.NewFDMap() + defer fdm.DecRef() + mounter := fs.FileOwnerFromContext(ctx) + + // Maps sandbox FD to host FD. + fdMap := map[int]int{ + 0: stdioFDs[0], + 1: stdioFDs[1], + 2: stdioFDs[2], + } + + var ttyFile *fs.File + for appFD, hostFD := range fdMap { + var appFile *fs.File + + if console && appFD < 3 { + // Import the file as a host TTY file. + if ttyFile == nil { + var err error + appFile, err = host.ImportFile(ctx, hostFD, mounter, true /* isTTY */) + if err != nil { + return nil, err + } + defer appFile.DecRef() + + // Remember this in the TTY file, as we will + // use it for the other stdio FDs. + ttyFile = appFile + } else { + // Re-use the existing TTY file, as all three + // stdio FDs must point to the same fs.File in + // order to share TTY state, specifically the + // foreground process group id. + appFile = ttyFile + } + } else { + // Import the file as a regular host file. + var err error + appFile, err = host.ImportFile(ctx, hostFD, mounter, false /* isTTY */) + if err != nil { + return nil, err + } + defer appFile.DecRef() + } + + // Add the file to the FD map. + if err := fdm.NewFDAt(kdefs.FD(appFD), appFile, kernel.FDFlags{}, l); err != nil { + return nil, err + } + } + + fdm.IncRef() + return fdm, nil +} |