diff --git a/pkg/sentry/fsimpl/gofer/dentry_impl.go b/pkg/sentry/fsimpl/gofer/dentry_impl.go index 8ebb4bb2c..8bace5dce 100644 --- a/pkg/sentry/fsimpl/gofer/dentry_impl.go +++ b/pkg/sentry/fsimpl/gofer/dentry_impl.go @@ -307,7 +307,7 @@ func (d *dentry) getXattrImpl(ctx context.Context, opts *vfs.GetXattrOptions) (s case *lisafsDentry: return dt.controlFD.GetXattr(ctx, opts.Name, opts.Size) case *directfsDentry: - return dt.getXattr(opts.Name, opts.Size) + return dt.getXattr(ctx, opts.Name, opts.Size) default: panic("unknown dentry implementation") } diff --git a/pkg/sentry/fsimpl/gofer/directfs_dentry.go b/pkg/sentry/fsimpl/gofer/directfs_dentry.go index 6d01ccbb1..5c54d0d56 100644 --- a/pkg/sentry/fsimpl/gofer/directfs_dentry.go +++ b/pkg/sentry/fsimpl/gofer/directfs_dentry.go @@ -423,7 +423,15 @@ func (d *directfsDentry) getHostChild(name string) (*dentry, error) { return d.fs.newDirectfsDentry(childFD) } -func (d *directfsDentry) getXattr(name string, size uint64) (string, error) { +func (d *directfsDentry) getXattr(ctx context.Context, name string, size uint64) (string, error) { + if ftype := d.fileType(); ftype == linux.S_IFSOCK || ftype == linux.S_IFLNK { + // Sockets and symlinks use O_PATH control FDs. However, fgetxattr(2) fails + // with EBADF for O_PATH FDs. Fallback to lisafs. + if err := d.ensureLisafsControlFD(ctx); err != nil { + return "", err + } + return d.controlFDLisa.GetXattr(ctx, name, size) + } data := make([]byte, size) if _, err := unix.Fgetxattr(d.controlFD, name, data); err != nil { return "", err diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index bd718a2cc..8f96bf584 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -105,6 +105,7 @@ var allowedSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_GETRANDOM: seccomp.MatchAll{}, unix.SYS_GETTID: seccomp.MatchAll{}, unix.SYS_GETTIMEOFDAY: seccomp.MatchAll{}, + unix.SYS_LGETXATTR: seccomp.MatchAll{}, unix.SYS_LSEEK: seccomp.MatchAll{}, unix.SYS_MADVISE: seccomp.MatchAll{}, unix.SYS_MEMFD_CREATE: seccomp.MatchAll{}, // Used by flipcall.PacketWindowAllocator.Init(). diff --git a/runsc/fsgofer/lisafs.go b/runsc/fsgofer/lisafs.go index d7ada02fb..d28dfc047 100644 --- a/runsc/fsgofer/lisafs.go +++ b/runsc/fsgofer/lisafs.go @@ -923,6 +923,12 @@ func (fd *controlFDLisa) Renamed() { // GetXattr implements lisafs.ControlFDImpl.GetXattr. func (fd *controlFDLisa) GetXattr(name string, size uint32, getValueBuf func(uint32) []byte) (uint16, error) { data := getValueBuf(size) + if fd.IsSocket() || fd.IsSymlink() { + // Sockets and symlinks use O_PATH host FDs. However, fgetxattr(2) fails + // with EBADF for O_PATH FDs. Use lgetxattr(2) instead. + xattrSize, err := unix.Lgetxattr(fd.Node().FilePath(), name, data) + return uint16(xattrSize), err + } xattrSize, err := unix.Fgetxattr(fd.hostFD, name, data) return uint16(xattrSize), err }