goferfs: Use lgetxattr(2) to get xattr for sockets and symlinks.

In goferfs, the control FD (in gofer client in directfs mode) and host FD in
fsgofer server is an O_PATH FD for socket and symlink files.

fgetxattr(2) fails with EBADF for O_PATH fds. So use lgetxattr(2) instead. This
is a path-based syscall, so it should work for symlinks and sockets. Since the
gofer client can not make path-based syscalls, it falls back to lisafs.

Fixes #11049
Updates #10385

PiperOrigin-RevId: 687160973
This commit is contained in:
Ayush Ranjan
2024-10-17 21:56:24 -07:00
committed by gVisor bot
parent dc926403d7
commit 7119403359
4 changed files with 17 additions and 2 deletions
+1 -1
View File
@@ -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")
}
+9 -1
View File
@@ -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
+1
View File
@@ -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().
+6
View File
@@ -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
}