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:
Jing Chen
2024-02-29 00:01:31 -08:00
committed by gVisor bot
parent c324b9b3fa
commit e7b59aa1b6
7 changed files with 28 additions and 7 deletions
+1 -2
View File
@@ -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) {
+7 -3
View File
@@ -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
+6
View File
@@ -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{},
},
})
}
-1
View File
@@ -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{},
})
+3
View File
@@ -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())
}
+3 -1
View File
@@ -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.