Delete fsbridge.

Updates #1624

PiperOrigin-RevId: 492286535
This commit is contained in:
Ayush Ranjan
2022-12-01 13:36:10 -08:00
committed by gVisor bot
parent f59f942d4f
commit 0bb834f4e2
23 changed files with 101 additions and 300 deletions
-21
View File
@@ -1,21 +0,0 @@
load("//tools:defs.bzl", "go_library")
licenses(["notice"])
go_library(
name = "fsbridge",
srcs = [
"bridge.go",
"vfs.go",
],
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/context",
"//pkg/fspath",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/memmap",
"//pkg/sentry/vfs",
"//pkg/usermem",
],
)
-55
View File
@@ -1,55 +0,0 @@
// Copyright 2020 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 fsbridge provides common interfaces to bridge between VFS1 and VFS2
// files.
// TODO(gvisor.dev/issue/1624): Delete this package.
package fsbridge
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/usermem"
)
// File provides a common interface to bridge between VFS1 and VFS2 files.
type File interface {
// PathnameWithDeleted returns an absolute pathname to vd, consistent with
// Linux's d_path(). In particular, if vd.Dentry() has been disowned,
// PathnameWithDeleted appends " (deleted)" to the returned pathname.
PathnameWithDeleted(ctx context.Context) string
// ReadFull read all contents from the file.
ReadFull(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error)
// ConfigureMMap mutates opts to implement mmap(2) for the file.
ConfigureMMap(context.Context, *memmap.MMapOpts) error
// Type returns the file type, e.g. linux.S_IFREG.
Type(context.Context) (linux.FileMode, error)
// IncRef increments reference.
IncRef()
// DecRef decrements reference.
DecRef(ctx context.Context)
}
// Lookup provides a common interface to open files.
type Lookup interface {
// OpenPath opens a file.
OpenPath(ctx context.Context, path string, opts vfs.OpenOptions, remainingTraversals *uint, resolveFinal bool) (File, error)
}
-142
View File
@@ -1,142 +0,0 @@
// Copyright 2020 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 fsbridge
import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/usermem"
)
// VFSFile implements File interface over vfs.FileDescription.
//
// +stateify savable
type VFSFile struct {
file *vfs.FileDescription
}
var _ File = (*VFSFile)(nil)
// NewVFSFile creates a new File over fs.File.
func NewVFSFile(file *vfs.FileDescription) File {
return &VFSFile{file: file}
}
// PathnameWithDeleted implements File.
func (f *VFSFile) PathnameWithDeleted(ctx context.Context) string {
root := vfs.RootFromContext(ctx)
defer root.DecRef(ctx)
vfsObj := f.file.VirtualDentry().Mount().Filesystem().VirtualFilesystem()
name, _ := vfsObj.PathnameWithDeleted(ctx, root, f.file.VirtualDentry())
return name
}
// ReadFull implements File.
func (f *VFSFile) ReadFull(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) {
var total int64
for dst.NumBytes() > 0 {
n, err := f.file.PRead(ctx, dst, offset+total, vfs.ReadOptions{})
total += n
if err == io.EOF && total != 0 {
return total, io.ErrUnexpectedEOF
} else if err != nil {
return total, err
}
dst = dst.DropFirst64(n)
}
return total, nil
}
// ConfigureMMap implements File.
func (f *VFSFile) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error {
return f.file.ConfigureMMap(ctx, opts)
}
// Type implements File.
func (f *VFSFile) Type(ctx context.Context) (linux.FileMode, error) {
stat, err := f.file.Stat(ctx, vfs.StatOptions{})
if err != nil {
return 0, err
}
return linux.FileMode(stat.Mode).FileType(), nil
}
// IncRef implements File.
func (f *VFSFile) IncRef() {
f.file.IncRef()
}
// DecRef implements File.
func (f *VFSFile) DecRef(ctx context.Context) {
f.file.DecRef(ctx)
}
// FileDescription returns the FileDescription represented by f. It does not
// take an additional reference on the returned FileDescription.
func (f *VFSFile) FileDescription() *vfs.FileDescription {
return f.file
}
// fsLookup implements Lookup interface using fs.File.
//
// +stateify savable
type vfsLookup struct {
mntns *vfs.MountNamespace
root vfs.VirtualDentry
workingDir vfs.VirtualDentry
}
var _ Lookup = (*vfsLookup)(nil)
// NewVFSLookup creates a new Lookup.
func NewVFSLookup(mntns *vfs.MountNamespace, root, workingDir vfs.VirtualDentry) Lookup {
return &vfsLookup{
mntns: mntns,
root: root,
workingDir: workingDir,
}
}
// OpenPath implements Lookup.
//
// remainingTraversals is not configurable, all callers are using the
// default anyways.
func (l *vfsLookup) OpenPath(ctx context.Context, pathname string, opts vfs.OpenOptions, _ *uint, resolveFinal bool) (File, error) {
vfsObj := l.root.Mount().Filesystem().VirtualFilesystem()
creds := auth.CredentialsFromContext(ctx)
path := fspath.Parse(pathname)
pop := &vfs.PathOperation{
Root: l.root,
Start: l.workingDir,
Path: path,
FollowFinalSymlink: resolveFinal,
}
if path.Absolute {
pop.Start = l.root
}
fd, err := vfsObj.OpenAt(ctx, creds, pop, &opts)
if err != nil {
return nil, err
}
return &VFSFile{file: fd}, nil
}
-1
View File
@@ -87,7 +87,6 @@ go_library(
"//pkg/log",
"//pkg/refs",
"//pkg/safemem",
"//pkg/sentry/fsbridge",
"//pkg/sentry/fsimpl/kernfs",
"//pkg/sentry/fsimpl/lock",
"//pkg/sentry/inet",
+1 -2
View File
@@ -24,7 +24,6 @@ import (
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -967,7 +966,7 @@ func (s *exeSymlink) Getlink(ctx context.Context, _ *vfs.Mount) (vfs.VirtualDent
}
defer exec.DecRef(ctx)
vd := exec.(*fsbridge.VFSFile).FileDescription().VirtualDentry()
vd := exec.VirtualDentry()
vd.IncRef()
return vd, "", nil
}
-1
View File
@@ -17,7 +17,6 @@ go_library(
"//pkg/fspath",
"//pkg/hostarch",
"//pkg/memutil",
"//pkg/sentry/fsbridge",
"//pkg/sentry/fsimpl/tmpfs",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
+1 -2
View File
@@ -25,7 +25,6 @@ import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/memutil"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -128,7 +127,7 @@ func CreateTask(ctx context.Context, name string, tc *kernel.ThreadGroup, mntns
return nil, err
}
m := mm.NewMemoryManager(k, k, k.SleepForAddressSpaceActivation)
m.SetExecutable(ctx, fsbridge.NewVFSFile(exe))
m.SetExecutable(ctx, exe)
creds := auth.CredentialsFromContext(ctx)
config := &kernel.TaskConfig{
-1
View File
@@ -306,7 +306,6 @@ go_library(
"//pkg/secio",
"//pkg/sentry/arch",
"//pkg/sentry/device",
"//pkg/sentry/fsbridge",
"//pkg/sentry/fsimpl/kernfs",
"//pkg/sentry/fsimpl/lock",
"//pkg/sentry/fsimpl/mqfs",
+4 -5
View File
@@ -47,7 +47,6 @@ import (
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/pipefs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/sockfs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/timerfd"
@@ -660,7 +659,7 @@ type CreateProcessArgs struct {
// File is a passed host FD pointing to a file to load as the init binary.
//
// This is checked if and only if Filename is "".
File fsbridge.File
File *vfs.FileDescription
// Argvv is a list of arguments.
Argv []string
@@ -839,7 +838,6 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
}
defer wd.DecRef(ctx)
}
opener := fsbridge.NewVFSLookup(mntns, root, wd)
fsContext := NewFSContext(root, wd, args.Umask)
tg := k.NewThreadGroup(args.PIDNamespace, NewSignalHandlers(), linux.SIGCHLD, args.Limits)
@@ -856,7 +854,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
args.File = nil
case args.File != nil:
// If File is set, take the File provided directly.
args.Filename = args.File.PathnameWithDeleted(ctx)
args.Filename = args.File.MappedName(ctx)
default:
// Otherwise look at Argv and see if the first argument is a valid path.
if len(args.Argv) == 0 {
@@ -871,7 +869,8 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
// Create a fresh task context.
remainingTraversals := args.MaxSymlinkTraversals
loadArgs := loader.LoadArgs{
Opener: opener,
Root: root,
WorkingDir: wd,
RemainingTraversals: &remainingTraversals,
ResolveFinal: true,
Filename: args.Filename,
+14 -17
View File
@@ -67,7 +67,6 @@ package kernel
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/seccheck"
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
@@ -92,7 +91,7 @@ func (*execStop) Killable() bool { return true }
//
// Preconditions: The caller must be running Task.doSyscallInvoke on the task
// goroutine.
func (t *Task) Execve(newImage *TaskImage, argv, env []string, executable fsbridge.File, pathname string) (*SyscallControl, error) {
func (t *Task) Execve(newImage *TaskImage, argv, env []string, executable *vfs.FileDescription, pathname string) (*SyscallControl, error) {
// We can't clearly hold kernel package locks while stat'ing executable.
if seccheck.Global.Enabled(seccheck.PointExecve) {
mask, info := getExecveSeccheckInfo(t, argv, env, executable, pathname)
@@ -303,7 +302,7 @@ func (t *Task) promoteLocked() {
oldLeader.exitNotifyLocked(false)
}
func getExecveSeccheckInfo(t *Task, argv, env []string, executable fsbridge.File, pathname string) (seccheck.FieldSet, *pb.ExecveInfo) {
func getExecveSeccheckInfo(t *Task, argv, env []string, executable *vfs.FileDescription, pathname string) (seccheck.FieldSet, *pb.ExecveInfo) {
fields := seccheck.Global.GetFieldSet(seccheck.PointExecve)
info := &pb.ExecveInfo{
Argv: argv,
@@ -311,21 +310,19 @@ func getExecveSeccheckInfo(t *Task, argv, env []string, executable fsbridge.File
}
if executable != nil {
info.BinaryPath = pathname
if vfs2bridgeFile, ok := executable.(*fsbridge.VFSFile); ok {
if fields.Local.Contains(seccheck.FieldSentryExecveBinaryInfo) {
statOpts := vfs.StatOptions{
Mask: linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_UID | linux.STATX_GID,
if fields.Local.Contains(seccheck.FieldSentryExecveBinaryInfo) {
statOpts := vfs.StatOptions{
Mask: linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_UID | linux.STATX_GID,
}
if stat, err := executable.Stat(t, statOpts); err == nil {
if stat.Mask&(linux.STATX_TYPE|linux.STATX_MODE) == (linux.STATX_TYPE | linux.STATX_MODE) {
info.BinaryMode = uint32(stat.Mode)
}
if stat, err := vfs2bridgeFile.FileDescription().Stat(t, statOpts); err == nil {
if stat.Mask&(linux.STATX_TYPE|linux.STATX_MODE) == (linux.STATX_TYPE | linux.STATX_MODE) {
info.BinaryMode = uint32(stat.Mode)
}
if stat.Mask&linux.STATX_UID != 0 {
info.BinaryUid = stat.UID
}
if stat.Mask&linux.STATX_GID != 0 {
info.BinaryGid = stat.GID
}
if stat.Mask&linux.STATX_UID != 0 {
info.BinaryUid = stat.UID
}
if stat.Mask&linux.STATX_GID != 0 {
info.BinaryGid = stat.GID
}
}
}
+1 -1
View File
@@ -253,6 +253,6 @@ func (t *Task) traceExecEvent(image *TaskImage) {
// traceExecEvent function may be called before the task goroutine
// starts, so we must use the async context.
name := file.PathnameWithDeleted(t.AsyncContext())
name := file.MappedName(t.AsyncContext())
trace.Logf(t.traceContext, traceCategory, "exec: %s", name)
}
+1 -1
View File
@@ -21,12 +21,12 @@ go_library(
"//pkg/context",
"//pkg/cpuid",
"//pkg/errors/linuxerr",
"//pkg/fspath",
"//pkg/hostarch",
"//pkg/log",
"//pkg/rand",
"//pkg/safemem",
"//pkg/sentry/arch",
"//pkg/sentry/fsbridge",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/limits",
"//pkg/sentry/loader/vdsodata",
+12 -12
View File
@@ -28,10 +28,10 @@ import (
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/usermem"
)
@@ -238,7 +238,7 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
// mapSegment maps a phdr into the Task. offset is the offset to apply to
// phdr.Vaddr.
func mapSegment(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, phdr *elf.ProgHeader, offset hostarch.Addr) error {
func mapSegment(ctx context.Context, m *mm.MemoryManager, fd *vfs.FileDescription, phdr *elf.ProgHeader, offset hostarch.Addr) error {
// We must make a page-aligned mapping.
adjust := hostarch.Addr(phdr.Vaddr).PageOffset()
@@ -286,7 +286,7 @@ func mapSegment(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, phdr
mopts.MappingIdentity.DecRef(ctx)
}
}()
if err := f.ConfigureMMap(ctx, &mopts); err != nil {
if err := fd.ConfigureMMap(ctx, &mopts); err != nil {
ctx.Infof("File is not memory-mappable: %v", err)
return err
}
@@ -405,7 +405,7 @@ type loadedELF struct {
// It does not load the ELF interpreter, or return any auxv entries.
//
// Preconditions: f is an ELF file.
func loadParsedELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, info elfInfo, sharedLoadOffset hostarch.Addr) (loadedELF, error) {
func loadParsedELF(ctx context.Context, m *mm.MemoryManager, fd *vfs.FileDescription, info elfInfo, sharedLoadOffset hostarch.Addr) (loadedELF, error) {
first := true
var start, end hostarch.Addr
var interpreter string
@@ -445,7 +445,7 @@ func loadParsedELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, in
}
path := make([]byte, phdr.Filesz)
_, err := f.ReadFull(ctx, usermem.BytesIOSequence(path), int64(phdr.Off))
_, err := fd.ReadFull(ctx, usermem.BytesIOSequence(path), int64(phdr.Off))
if err != nil {
// If an interpreter was specified, it should exist.
ctx.Infof("Error reading PT_INTERP path: %v", err)
@@ -542,7 +542,7 @@ func loadParsedELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, in
continue
}
if err := mapSegment(ctx, m, f, &phdr, offset); err != nil {
if err := mapSegment(ctx, m, fd, &phdr, offset); err != nil {
ctx.Infof("Failed to map PT_LOAD segment: %+v", phdr)
return loadedELF{}, err
}
@@ -580,8 +580,8 @@ func loadParsedELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, in
// Preconditions:
// - f is an ELF file.
// - f is the first ELF loaded into m.
func loadInitialELF(ctx context.Context, m *mm.MemoryManager, fs cpuid.FeatureSet, f fsbridge.File) (loadedELF, *arch.Context64, error) {
info, err := parseHeader(ctx, f)
func loadInitialELF(ctx context.Context, m *mm.MemoryManager, fs cpuid.FeatureSet, fd *vfs.FileDescription) (loadedELF, *arch.Context64, error) {
info, err := parseHeader(ctx, fd)
if err != nil {
ctx.Infof("Failed to parse initial ELF: %v", err)
return loadedELF{}, nil, err
@@ -606,7 +606,7 @@ func loadInitialELF(ctx context.Context, m *mm.MemoryManager, fs cpuid.FeatureSe
// PIELoadAddress tries to move the ELF out of the way of the default
// mmap base to ensure that the initial brk has sufficient space to
// grow.
le, err := loadParsedELF(ctx, m, f, info, ac.PIELoadAddress(l))
le, err := loadParsedELF(ctx, m, fd, info, ac.PIELoadAddress(l))
return le, ac, err
}
@@ -617,8 +617,8 @@ func loadInitialELF(ctx context.Context, m *mm.MemoryManager, fs cpuid.FeatureSe
// It does not return any auxv entries.
//
// Preconditions: f is an ELF file.
func loadInterpreterELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.File, initial loadedELF) (loadedELF, error) {
info, err := parseHeader(ctx, f)
func loadInterpreterELF(ctx context.Context, m *mm.MemoryManager, fd *vfs.FileDescription, initial loadedELF) (loadedELF, error) {
info, err := parseHeader(ctx, fd)
if err != nil {
if linuxerr.Equals(linuxerr.ENOEXEC, err) {
// Bad interpreter.
@@ -638,7 +638,7 @@ func loadInterpreterELF(ctx context.Context, m *mm.MemoryManager, f fsbridge.Fil
// The interpreter is not given a load offset, as its location does not
// affect brk.
return loadParsedELF(ctx, m, f, info, 0)
return loadParsedELF(ctx, m, fd, info, 0)
}
// loadELF loads args.File into the Task address space.
+3 -3
View File
@@ -20,7 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/usermem"
)
@@ -37,9 +37,9 @@ const (
)
// parseInterpreterScript returns the interpreter path and argv.
func parseInterpreterScript(ctx context.Context, filename string, f fsbridge.File, argv []string) (newpath string, newargv []string, err error) {
func parseInterpreterScript(ctx context.Context, filename string, fd *vfs.FileDescription, argv []string) (newpath string, newargv []string, err error) {
line := make([]byte, interpMaxLineLength)
n, err := f.ReadFull(ctx, usermem.BytesIOSequence(line), 0)
n, err := fd.ReadFull(ctx, usermem.BytesIOSequence(line), 0)
// Short read is OK.
if err != nil && err != io.ErrUnexpectedEOF {
if err == io.EOF {
+31 -16
View File
@@ -27,10 +27,10 @@ import (
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/rand"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/vfs"
@@ -55,18 +55,21 @@ type LoadArgs struct {
// Filename is the path for the executable.
Filename string
// File is an open fs.File object of the executable. If File is not
// nil, then File will be loaded and Filename will be ignored.
// File is an open FD of the executable. If File is not nil, then File will
// be loaded and Filename will be ignored.
//
// The caller is responsible for checking that the user can execute this file.
File fsbridge.File
File *vfs.FileDescription
// Opener is used to open the executable file when 'File' is nil.
Opener fsbridge.Lookup
// Root is the current filesystem root.
Root vfs.VirtualDentry
// WorkingDir is the current working directory.
WorkingDir vfs.VirtualDentry
// If AfterOpen is not nil, it is called after every successful call to
// Opener.OpenPath().
AfterOpen func(f fsbridge.File)
AfterOpen func(f *vfs.FileDescription)
// CloseOnExec indicates that the executable (or one of its parent
// directories) was opened with O_CLOEXEC. If the executable is an
@@ -91,7 +94,7 @@ type LoadArgs struct {
// installed in the Task FDTable. The caller takes ownership of both.
//
// args.Filename must be a readable, executable, regular file.
func openPath(ctx context.Context, args LoadArgs) (fsbridge.File, error) {
func openPath(ctx context.Context, args LoadArgs) (*vfs.FileDescription, error) {
if args.Filename == "" {
ctx.Infof("cannot open empty name")
return nil, linuxerr.ENOENT
@@ -106,23 +109,35 @@ func openPath(ctx context.Context, args LoadArgs) (fsbridge.File, error) {
Flags: linux.O_RDONLY,
FileExec: true,
}
f, err := args.Opener.OpenPath(ctx, args.Filename, opts, args.RemainingTraversals, args.ResolveFinal)
vfsObj := args.Root.Mount().Filesystem().VirtualFilesystem()
creds := auth.CredentialsFromContext(ctx)
path := fspath.Parse(args.Filename)
pop := &vfs.PathOperation{
Root: args.Root,
Start: args.WorkingDir,
Path: path,
FollowFinalSymlink: args.ResolveFinal,
}
if path.Absolute {
pop.Start = args.Root
}
fd, err := vfsObj.OpenAt(ctx, creds, pop, &opts)
if err != nil {
return f, err
return nil, err
}
if args.AfterOpen != nil {
args.AfterOpen(f)
args.AfterOpen(fd)
}
return f, nil
return fd, nil
}
// checkIsRegularFile prevents us from trying to execute a directory, pipe, etc.
func checkIsRegularFile(ctx context.Context, file fsbridge.File, filename string) error {
t, err := file.Type(ctx)
func checkIsRegularFile(ctx context.Context, fd *vfs.FileDescription, filename string) error {
stat, err := fd.Stat(ctx, vfs.StatOptions{})
if err != nil {
return err
}
if t != linux.ModeRegular {
if t := linux.FileMode(stat.Mode).FileType(); t != linux.ModeRegular {
ctx.Infof("%q is not a regular file: %v", filename, t)
return linuxerr.EACCES
}
@@ -157,7 +172,7 @@ const (
// - arch.Context64 matching the binary arch
// - fs.Dirent of the binary file
// - Possibly updated args.Argv
func loadExecutable(ctx context.Context, args LoadArgs) (loadedELF, *arch.Context64, fsbridge.File, []string, error) {
func loadExecutable(ctx context.Context, args LoadArgs) (loadedELF, *arch.Context64, *vfs.FileDescription, []string, error) {
for i := 0; i < maxLoaderAttempts; i++ {
if args.File == nil {
var err error
+1 -1
View File
@@ -182,7 +182,6 @@ go_library(
"//pkg/safecopy",
"//pkg/safemem",
"//pkg/sentry/arch",
"//pkg/sentry/fsbridge",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/futex",
"//pkg/sentry/kernel/shm",
@@ -191,6 +190,7 @@ go_library(
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
"//pkg/sentry/usage",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/sync/locking",
"//pkg/usermem",
+5 -5
View File
@@ -18,7 +18,7 @@ import (
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
// Dumpability describes if and how core dumps should be created.
@@ -129,7 +129,7 @@ func (mm *MemoryManager) SetAuxv(auxv arch.Auxv) {
//
// An additional reference will be taken in the case of a non-nil executable,
// which must be released by the caller.
func (mm *MemoryManager) Executable() fsbridge.File {
func (mm *MemoryManager) Executable() *vfs.FileDescription {
mm.metadataMu.Lock()
defer mm.metadataMu.Unlock()
@@ -144,15 +144,15 @@ func (mm *MemoryManager) Executable() fsbridge.File {
// SetExecutable sets the executable.
//
// This takes a reference on d.
func (mm *MemoryManager) SetExecutable(ctx context.Context, file fsbridge.File) {
func (mm *MemoryManager) SetExecutable(ctx context.Context, fd *vfs.FileDescription) {
mm.metadataMu.Lock()
// Grab a new reference.
file.IncRef()
fd.IncRef()
// Set the executable.
orig := mm.executable
mm.executable = file
mm.executable = fd
mm.metadataMu.Unlock()
+2 -2
View File
@@ -44,10 +44,10 @@ import (
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
// MapsCallbackFunc has all the parameters required for populating an entry of /proc/[pid]/maps.
@@ -226,7 +226,7 @@ type MemoryManager struct {
// is not nil, it holds a reference on the Dirent.
//
// executable is protected by metadataMu.
executable fsbridge.File
executable *vfs.FileDescription
// aioManager keeps track of AIOContexts used for async IOs. AIOManager
// must be cloned when CLONE_VM is used.
-1
View File
@@ -79,7 +79,6 @@ go_library(
"//pkg/rand",
"//pkg/safemem",
"//pkg/sentry/arch",
"//pkg/sentry/fsbridge",
"//pkg/sentry/fsimpl/eventfd",
"//pkg/sentry/fsimpl/host",
"//pkg/sentry/fsimpl/iouringfs",
+1 -2
View File
@@ -21,7 +21,6 @@ import (
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/marshal/primitive"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/mm"
@@ -141,7 +140,7 @@ func Prctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
}
// Set the underlying executable.
t.MemoryManager().SetExecutable(t, fsbridge.NewVFSFile(file))
t.MemoryManager().SetExecutable(t, file)
case linux.PR_SET_MM_AUXV,
linux.PR_SET_MM_START_CODE,

Some files were not shown because too many files have changed in this diff Show More