summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/fsimpl/host/host.go16
-rw-r--r--pkg/sentry/fsimpl/sockfs/sockfs.go26
-rw-r--r--pkg/sentry/kernel/kernel.go42
-rw-r--r--runsc/boot/fds.go7
-rw-r--r--runsc/boot/loader.go13
5 files changed, 64 insertions, 40 deletions
diff --git a/pkg/sentry/fsimpl/host/host.go b/pkg/sentry/fsimpl/host/host.go
index 7847e3cc2..a26b13067 100644
--- a/pkg/sentry/fsimpl/host/host.go
+++ b/pkg/sentry/fsimpl/host/host.go
@@ -42,7 +42,7 @@ type filesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (filesystemType) GetFilesystem(context.Context, *vfs.VirtualFilesystem, *auth.Credentials, string, vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
- panic("cannot instaniate a host filesystem")
+ panic("host.filesystemType.GetFilesystem should never be called")
}
// Name implements FilesystemType.Name.
@@ -55,14 +55,14 @@ type filesystem struct {
kernfs.Filesystem
}
-// NewMount returns a new disconnected mount in vfsObj that may be passed to ImportFD.
-func NewMount(vfsObj *vfs.VirtualFilesystem) (*vfs.Mount, error) {
+// NewFilesystem sets up and returns a new hostfs filesystem.
+//
+// Note that there should only ever be one instance of host.filesystem,
+// a global mount for host fds.
+func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
fs := &filesystem{}
- fs.Init(vfsObj, &filesystemType{})
- vfsfs := fs.VFSFilesystem()
- // NewDisconnectedMount will take an additional reference on vfsfs.
- defer vfsfs.DecRef()
- return vfsObj.NewDisconnectedMount(vfsfs, nil, &vfs.MountOptions{})
+ fs.Init(vfsObj, filesystemType{})
+ return fs.VFSFilesystem()
}
// ImportFD sets up and returns a vfs.FileDescription from a donated fd.
diff --git a/pkg/sentry/fsimpl/sockfs/sockfs.go b/pkg/sentry/fsimpl/sockfs/sockfs.go
index 3f7ad1d65..632cfde88 100644
--- a/pkg/sentry/fsimpl/sockfs/sockfs.go
+++ b/pkg/sentry/fsimpl/sockfs/sockfs.go
@@ -24,26 +24,12 @@ import (
"gvisor.dev/gvisor/pkg/syserror"
)
-// NewFilesystem creates a new sockfs filesystem.
-//
-// Note that there should only ever be one instance of sockfs.Filesystem,
-// backing a global socket mount.
-func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
- fs, _, err := filesystemType{}.GetFilesystem(nil, vfsObj, nil, "", vfs.GetFilesystemOptions{})
- if err != nil {
- panic("failed to create sockfs filesystem")
- }
- return fs
-}
-
// filesystemType implements vfs.FilesystemType.
type filesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (fsType filesystemType) GetFilesystem(_ context.Context, vfsObj *vfs.VirtualFilesystem, _ *auth.Credentials, _ string, _ vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
- fs := &filesystem{}
- fs.Init(vfsObj, fsType)
- return fs.VFSFilesystem(), nil, nil
+ panic("sockfs.filesystemType.GetFilesystem should never be called")
}
// Name implements FilesystemType.Name.
@@ -60,6 +46,16 @@ type filesystem struct {
kernfs.Filesystem
}
+// NewFilesystem sets up and returns a new sockfs filesystem.
+//
+// Note that there should only ever be one instance of sockfs.Filesystem,
+// backing a global socket mount.
+func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
+ fs := &filesystem{}
+ fs.Init(vfsObj, filesystemType{})
+ return fs.VFSFilesystem()
+}
+
// inode implements kernfs.Inode.
//
// TODO(gvisor.dev/issue/1476): Add device numbers to this inode (which are
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go
index fef60e636..c91b9dce2 100644
--- a/pkg/sentry/kernel/kernel.go
+++ b/pkg/sentry/kernel/kernel.go
@@ -227,11 +227,6 @@ type Kernel struct {
// by extMu.
nextSocketEntry uint64
- // socketMount is a disconnected vfs.Mount, not included in k.vfs,
- // representing a sockfs.filesystem. socketMount is used to back
- // VirtualDentries representing anonymous sockets.
- socketMount *vfs.Mount
-
// deviceRegistry is used to save/restore device.SimpleDevices.
deviceRegistry struct{} `state:".(*device.Registry)"`
@@ -255,10 +250,22 @@ type Kernel struct {
// VFS keeps the filesystem state used across the kernel.
vfs vfs.VirtualFilesystem
+ // hostMount is the Mount used for file descriptors that were imported
+ // from the host.
+ hostMount *vfs.Mount
+
// pipeMount is the Mount used for pipes created by the pipe() and pipe2()
// syscalls (as opposed to named pipes created by mknod()).
pipeMount *vfs.Mount
+ // socketMount is the Mount used for sockets created by the socket() and
+ // socketpair() syscalls. There are several cases where a socket dentry will
+ // not be contained in socketMount:
+ // 1. Socket files created by mknod()
+ // 2. Socket fds imported from the host (Kernel.hostMount is used for these)
+ // 3. Socket files created by binding Unix sockets to a file path
+ socketMount *vfs.Mount
+
// If set to true, report address space activation waits as if the task is in
// external wait so that the watchdog doesn't report the task stuck.
SleepForAddressSpaceActivation bool
@@ -377,7 +384,7 @@ func (k *Kernel) Init(args InitKernelArgs) error {
defer socketFilesystem.DecRef()
socketMount, err := k.vfs.NewDisconnectedMount(socketFilesystem, nil, &vfs.MountOptions{})
if err != nil {
- return fmt.Errorf("failed to initialize socket mount: %v", err)
+ return fmt.Errorf("failed to create sockfs mount: %v", err)
}
k.socketMount = socketMount
}
@@ -1526,11 +1533,6 @@ func (k *Kernel) ListSockets() []*SocketEntry {
return socks
}
-// SocketMount returns the global socket mount.
-func (k *Kernel) SocketMount() *vfs.Mount {
- return k.socketMount
-}
-
// supervisorContext is a privileged context.
type supervisorContext struct {
context.NoopSleeper
@@ -1629,7 +1631,25 @@ func (k *Kernel) VFS() *vfs.VirtualFilesystem {
return &k.vfs
}
+// SetHostMount sets the hostfs mount.
+func (k *Kernel) SetHostMount(mnt *vfs.Mount) {
+ if k.hostMount != nil {
+ panic("Kernel.hostMount cannot be set more than once")
+ }
+ k.hostMount = mnt
+}
+
+// HostMount returns the hostfs mount.
+func (k *Kernel) HostMount() *vfs.Mount {
+ return k.hostMount
+}
+
// PipeMount returns the pipefs mount.
func (k *Kernel) PipeMount() *vfs.Mount {
return k.pipeMount
}
+
+// SocketMount returns the sockfs mount.
+func (k *Kernel) SocketMount() *vfs.Mount {
+ return k.socketMount
+}
diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go
index 7e49f6f9f..0cbd63857 100644
--- a/runsc/boot/fds.go
+++ b/runsc/boot/fds.go
@@ -89,14 +89,9 @@ func createFDTableVFS2(ctx context.Context, console bool, stdioFDs []int) (*kern
fdTable := k.NewFDTable()
defer fdTable.DecRef()
- hostMount, err := vfshost.NewMount(k.VFS())
- if err != nil {
- return nil, fmt.Errorf("creating host mount: %w", err)
- }
-
for appFD, hostFD := range stdioFDs {
// TODO(gvisor.dev/issue/1482): Add TTY support.
- appFile, err := vfshost.ImportFD(hostMount, hostFD, false)
+ appFile, err := vfshost.ImportFD(k.HostMount(), hostFD, false)
if err != nil {
return nil, err
}
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index 096b0e9f0..3f41d8357 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -36,6 +36,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/host"
"gvisor.dev/gvisor/pkg/sentry/fs/user"
+ vfs2host "gvisor.dev/gvisor/pkg/sentry/fsimpl/host"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -46,6 +47,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/syscalls/linux/vfs2"
"gvisor.dev/gvisor/pkg/sentry/time"
"gvisor.dev/gvisor/pkg/sentry/usage"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sentry/watchdog"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/tcpip"
@@ -329,6 +331,17 @@ func New(args Args) (*Loader, error) {
return nil, fmt.Errorf("creating pod mount hints: %v", err)
}
+ if kernel.VFS2Enabled {
+ // Set up host mount that will be used for imported fds.
+ hostFilesystem := vfs2host.NewFilesystem(k.VFS())
+ defer hostFilesystem.DecRef()
+ hostMount, err := k.VFS().NewDisconnectedMount(hostFilesystem, nil, &vfs.MountOptions{})
+ if err != nil {
+ return nil, fmt.Errorf("failed to create hostfs mount: %v", err)
+ }
+ k.SetHostMount(hostMount)
+ }
+
// Make host FDs stable between invocations. Host FDs must map to the exact
// same number when the sandbox is restored. Otherwise the wrong FD will be
// used.