mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add BoundEndpointAt filesystem operation.
BoundEndpointAt() is needed to support Unix sockets bound at a file path, corresponding to BoundEndpoint() in VFS1. Updates #1476. PiperOrigin-RevId: 303258251
This commit is contained in:
@@ -45,6 +45,7 @@ go_library(
|
||||
"//pkg/sentry/fsimpl/ext/disklayout",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sentry/syscalls/linux",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/sync",
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
@@ -463,6 +464,17 @@ func (fs *filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
return syserror.EROFS
|
||||
}
|
||||
|
||||
// BoundEndpointAt implements FilesystemImpl.BoundEndpointAt.
|
||||
func (fs *filesystem) BoundEndpointAt(ctx context.Context, rp *vfs.ResolvingPath) (transport.BoundEndpoint, error) {
|
||||
_, _, err := fs.walk(rp, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(b/134676337): Support sockets.
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
|
||||
// ListxattrAt implements vfs.FilesystemImpl.ListxattrAt.
|
||||
func (fs *filesystem) ListxattrAt(ctx context.Context, rp *vfs.ResolvingPath) ([]string, error) {
|
||||
_, _, err := fs.walk(rp, false)
|
||||
|
||||
@@ -46,6 +46,7 @@ go_library(
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/pgalloc",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/syserror",
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/p9"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
@@ -1059,6 +1060,13 @@ func (fs *filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
return fs.unlinkAt(ctx, rp, false /* dir */)
|
||||
}
|
||||
|
||||
// BoundEndpointAt implements FilesystemImpl.BoundEndpointAt.
|
||||
//
|
||||
// TODO(gvisor.dev/issue/1476): Implement BoundEndpointAt.
|
||||
func (fs *filesystem) BoundEndpointAt(ctx context.Context, rp *vfs.ResolvingPath) (transport.BoundEndpoint, error) {
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
|
||||
// ListxattrAt implements vfs.FilesystemImpl.ListxattrAt.
|
||||
func (fs *filesystem) ListxattrAt(ctx context.Context, rp *vfs.ResolvingPath) ([]string, error) {
|
||||
var ds *[]*dentry
|
||||
|
||||
@@ -35,6 +35,7 @@ go_library(
|
||||
"//pkg/refs",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/sync",
|
||||
"//pkg/syserror",
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
@@ -728,6 +729,18 @@ func (fs *Filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// BoundEndpointAt implements FilesystemImpl.BoundEndpointAt.
|
||||
func (fs *Filesystem) BoundEndpointAt(ctx context.Context, rp *vfs.ResolvingPath) (transport.BoundEndpoint, error) {
|
||||
fs.mu.RLock()
|
||||
_, _, err := fs.walkExistingLocked(ctx, rp)
|
||||
fs.mu.RUnlock()
|
||||
fs.processDeferredDecRefs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
|
||||
// ListxattrAt implements vfs.FilesystemImpl.ListxattrAt.
|
||||
func (fs *Filesystem) ListxattrAt(ctx context.Context, rp *vfs.ResolvingPath) ([]string, error) {
|
||||
fs.mu.RLock()
|
||||
|
||||
@@ -46,6 +46,7 @@ go_library(
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/pgalloc",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/sentry/vfs/lock",
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
@@ -656,6 +657,13 @@ func (fs *filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// BoundEndpointAt implements FilesystemImpl.BoundEndpointAt.
|
||||
//
|
||||
// TODO(gvisor.dev/issue/1476): Implement BoundEndpointAt.
|
||||
func (fs *filesystem) BoundEndpointAt(ctx context.Context, rp *vfs.ResolvingPath) (transport.BoundEndpoint, error) {
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
|
||||
// ListxattrAt implements vfs.FilesystemImpl.ListxattrAt.
|
||||
func (fs *filesystem) ListxattrAt(ctx context.Context, rp *vfs.ResolvingPath) ([]string, error) {
|
||||
fs.mu.RLock()
|
||||
|
||||
@@ -53,6 +53,7 @@ go_library(
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/limits",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sync",
|
||||
"//pkg/syserror",
|
||||
"//pkg/usermem",
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
@@ -222,6 +223,14 @@ func (fs *anonFilesystem) UnlinkAt(ctx context.Context, rp *ResolvingPath) error
|
||||
return syserror.EPERM
|
||||
}
|
||||
|
||||
// BoundEndpointAt implements FilesystemImpl.BoundEndpointAt.
|
||||
func (fs *anonFilesystem) BoundEndpointAt(ctx context.Context, rp *ResolvingPath) (transport.BoundEndpoint, error) {
|
||||
if !rp.Final() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
|
||||
// ListxattrAt implements FilesystemImpl.ListxattrAt.
|
||||
func (fs *anonFilesystem) ListxattrAt(ctx context.Context, rp *ResolvingPath) ([]string, error) {
|
||||
if !rp.Done() {
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
)
|
||||
|
||||
// A Filesystem is a tree of nodes represented by Dentries, which forms part of
|
||||
@@ -460,6 +461,11 @@ type FilesystemImpl interface {
|
||||
// RemovexattrAt returns ENOTSUP.
|
||||
RemovexattrAt(ctx context.Context, rp *ResolvingPath, name string) error
|
||||
|
||||
// BoundEndpointAt returns the Unix socket endpoint bound at the path rp.
|
||||
//
|
||||
// - If a non-socket file exists at rp, then BoundEndpointAt returns ECONNREFUSED.
|
||||
BoundEndpointAt(ctx context.Context, rp *ResolvingPath) (transport.BoundEndpoint, error)
|
||||
|
||||
// PrependPath prepends a path from vd to vd.Mount().Root() to b.
|
||||
//
|
||||
// If vfsroot.Ok(), it is the contextual VFS root; if it is encountered
|
||||
@@ -482,7 +488,7 @@ type FilesystemImpl interface {
|
||||
// Preconditions: vd.Mount().Filesystem().Impl() == this FilesystemImpl.
|
||||
PrependPath(ctx context.Context, vfsroot, vd VirtualDentry, b *fspath.Builder) error
|
||||
|
||||
// TODO: inotify_add_watch(); bind()
|
||||
// TODO: inotify_add_watch()
|
||||
}
|
||||
|
||||
// PrependPathAtVFSRootError is returned by implementations of
|
||||
|
||||
+36
-8
@@ -38,6 +38,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
@@ -230,7 +231,7 @@ func (vfs *VirtualFilesystem) getParentDirAndName(ctx context.Context, creds *au
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.GetParentDentryAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.GetParentDentryAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -271,7 +272,7 @@ func (vfs *VirtualFilesystem) LinkAt(ctx context.Context, creds *auth.Credential
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.LinkAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.LinkAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -307,7 +308,7 @@ func (vfs *VirtualFilesystem) MkdirAt(ctx context.Context, creds *auth.Credentia
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.MkdirAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.MkdirAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -340,7 +341,7 @@ func (vfs *VirtualFilesystem) MknodAt(ctx context.Context, creds *auth.Credentia
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.MknodAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.MknodAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -350,6 +351,33 @@ func (vfs *VirtualFilesystem) MknodAt(ctx context.Context, creds *auth.Credentia
|
||||
}
|
||||
}
|
||||
|
||||
// BoundEndpointAt gets the bound endpoint at the given path, if one exists.
|
||||
func (vfs *VirtualFilesystem) BoundEndpointAt(ctx context.Context, creds *auth.Credentials, pop *PathOperation) (transport.BoundEndpoint, error) {
|
||||
if !pop.Path.Begin.Ok() {
|
||||
if pop.Path.Absolute {
|
||||
return nil, syserror.ECONNREFUSED
|
||||
}
|
||||
return nil, syserror.ENOENT
|
||||
}
|
||||
rp := vfs.getResolvingPath(creds, pop)
|
||||
for {
|
||||
bep, err := rp.mount.fs.impl.BoundEndpointAt(ctx, rp)
|
||||
if err == nil {
|
||||
vfs.putResolvingPath(rp)
|
||||
return bep, nil
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.BoundEndpointAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
vfs.putResolvingPath(rp)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAt returns a FileDescription providing access to the file at the given
|
||||
// path. A reference is taken on the returned FileDescription.
|
||||
func (vfs *VirtualFilesystem) OpenAt(ctx context.Context, creds *auth.Credentials, pop *PathOperation, opts *OpenOptions) (*FileDescription, error) {
|
||||
@@ -494,7 +522,7 @@ func (vfs *VirtualFilesystem) RenameAt(ctx context.Context, creds *auth.Credenti
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.RenameAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.RenameAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -527,7 +555,7 @@ func (vfs *VirtualFilesystem) RmdirAt(ctx context.Context, creds *auth.Credentia
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.RmdirAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.RmdirAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -608,7 +636,7 @@ func (vfs *VirtualFilesystem) SymlinkAt(ctx context.Context, creds *auth.Credent
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.SymlinkAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.SymlinkAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
@@ -640,7 +668,7 @@ func (vfs *VirtualFilesystem) UnlinkAt(ctx context.Context, creds *auth.Credenti
|
||||
}
|
||||
if checkInvariants {
|
||||
if rp.canHandleError(err) && rp.Done() {
|
||||
panic(fmt.Sprintf("%T.UnlinkAt() consumed all path components and returned %T", rp.mount.fs.impl, err))
|
||||
panic(fmt.Sprintf("%T.UnlinkAt() consumed all path components and returned %v", rp.mount.fs.impl, err))
|
||||
}
|
||||
}
|
||||
if !rp.handleError(err) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
var (
|
||||
E2BIG = error(syscall.E2BIG)
|
||||
EACCES = error(syscall.EACCES)
|
||||
EADDRINUSE = error(syscall.EADDRINUSE)
|
||||
EAGAIN = error(syscall.EAGAIN)
|
||||
EBADF = error(syscall.EBADF)
|
||||
EBADFD = error(syscall.EBADFD)
|
||||
|
||||
Reference in New Issue
Block a user