mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user