mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Implement Getxattr for directfs and lisafs.
It allows us to read the executable binary's security.capability. PiperOrigin-RevId: 611364676
This commit is contained in:
@@ -306,8 +306,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:
|
||||
// Consistent with runsc/fsgofer.
|
||||
return "", linuxerr.EOPNOTSUPP
|
||||
return dt.getXattr(opts.Name, opts.Size)
|
||||
default:
|
||||
panic("unknown dentry implementation")
|
||||
}
|
||||
|
||||
@@ -423,6 +423,14 @@ func (d *directfsDentry) getHostChild(name string) (*dentry, error) {
|
||||
return d.fs.newDirectfsDentry(childFD)
|
||||
}
|
||||
|
||||
func (d *directfsDentry) getXattr(name string, size uint64) (string, error) {
|
||||
data := make([]byte, size)
|
||||
if _, err := unix.Fgetxattr(d.controlFD, name, data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// getCreatedChild opens the newly created child, sets its uid/gid, constructs
|
||||
// a disconnected dentry and returns it.
|
||||
func (d *directfsDentry) getCreatedChild(name string, uid, gid int, isDir bool) (*dentry, error) {
|
||||
|
||||
@@ -101,6 +101,9 @@ func getxattr(t *kernel.Task, args arch.SyscallArguments, shouldFollowFinalSymli
|
||||
valueAddr := args[2].Pointer()
|
||||
size := args[3].SizeT()
|
||||
|
||||
if size > linux.XATTR_SIZE_MAX {
|
||||
size = linux.XATTR_SIZE_MAX
|
||||
}
|
||||
path, err := copyInPath(t, pathAddr)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@@ -137,6 +140,10 @@ func Fgetxattr(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintp
|
||||
valueAddr := args[2].Pointer()
|
||||
size := args[3].SizeT()
|
||||
|
||||
if size > linux.XATTR_SIZE_MAX {
|
||||
size = linux.XATTR_SIZE_MAX
|
||||
}
|
||||
|
||||
file := t.GetFile(fd)
|
||||
if file == nil {
|
||||
return 0, nil, linuxerr.EBADF
|
||||
@@ -339,9 +346,6 @@ func copyInXattrValue(t *kernel.Task, valueAddr hostarch.Addr, size uint) (strin
|
||||
}
|
||||
|
||||
func copyOutXattrValue(t *kernel.Task, valueAddr hostarch.Addr, size uint, value string) (int, error) {
|
||||
if size > linux.XATTR_SIZE_MAX {
|
||||
size = linux.XATTR_SIZE_MAX
|
||||
}
|
||||
if size == 0 {
|
||||
// Return the size that would be required to accommodate the value.
|
||||
return len(value), nil
|
||||
|
||||
@@ -408,5 +408,11 @@ func hostFilesystemFilters() seccomp.SyscallRules {
|
||||
seccomp.AnyValue{},
|
||||
seccomp.AnyValue{},
|
||||
},
|
||||
unix.SYS_FGETXATTR: seccomp.PerArg{
|
||||
seccomp.NonNegativeFD{},
|
||||
seccomp.AnyValue{},
|
||||
seccomp.AnyValue{},
|
||||
seccomp.AnyValue{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -233,5 +233,4 @@ var udsCreateSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule
|
||||
|
||||
var xattrSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{
|
||||
unix.SYS_FGETXATTR: seccomp.MatchAll{},
|
||||
unix.SYS_FSETXATTR: seccomp.MatchAll{},
|
||||
})
|
||||
|
||||
@@ -53,6 +53,9 @@ func Install(opt Options) error {
|
||||
// when not enabled.
|
||||
s.Merge(instrumentationFilters())
|
||||
|
||||
// TODO(b/317993245): add HostFilesystem to Options.
|
||||
s.Merge(xattrSyscalls)
|
||||
|
||||
return seccomp.Install(s, seccomp.DenyNewExecMappings, seccomp.DefaultProgramOptions())
|
||||
}
|
||||
|
||||
|
||||
@@ -901,7 +901,9 @@ func (fd *controlFDLisa) Renamed() {
|
||||
|
||||
// GetXattr implements lisafs.ControlFDImpl.GetXattr.
|
||||
func (fd *controlFDLisa) GetXattr(name string, size uint32, getValueBuf func(uint32) []byte) (uint16, error) {
|
||||
return 0, unix.EOPNOTSUPP
|
||||
data := getValueBuf(size)
|
||||
xattrSize, err := unix.Fgetxattr(fd.hostFD, name, data)
|
||||
return uint16(xattrSize), err
|
||||
}
|
||||
|
||||
// SetXattr implements lisafs.ControlFDImpl.SetXattr.
|
||||
|
||||
Reference in New Issue
Block a user