summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDean Deng <deandeng@google.com>2020-02-10 14:47:00 -0800
committergVisor bot <gvisor-bot@google.com>2020-02-10 14:47:47 -0800
commit475316e87dac806d69bcb06ea4065f3c138bb47e (patch)
treef4dbb10404a2d3a08ee6b327b474543979808477
parentafcab8fe9f6fb3504ebdbb95d35299277c2d67ca (diff)
Refactor getxattr.
Put most of the logic for getxattr in one place for clarity. This simplifies FGetXattr and getXattrFromPath, which are just wrappers for getXattr. PiperOrigin-RevId: 294308332
-rw-r--r--pkg/sentry/syscalls/linux/sys_xattr.go44
1 files changed, 20 insertions, 24 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_xattr.go b/pkg/sentry/syscalls/linux/sys_xattr.go
index 342337726..9d8140b8a 100644
--- a/pkg/sentry/syscalls/linux/sys_xattr.go
+++ b/pkg/sentry/syscalls/linux/sys_xattr.go
@@ -49,14 +49,11 @@ func FGetXattr(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys
}
defer f.DecRef()
- n, value, err := getXattr(t, f.Dirent, nameAddr, size)
+ n, err := getXattr(t, f.Dirent, nameAddr, valueAddr, size)
if err != nil {
return 0, nil, err
}
- if _, err := t.CopyOutBytes(valueAddr, []byte(value)); err != nil {
- return 0, nil, err
- }
return uintptr(n), nil, nil
}
@@ -71,41 +68,36 @@ func getXattrFromPath(t *kernel.Task, args arch.SyscallArguments, resolveSymlink
return 0, nil, err
}
- valueLen := 0
+ n := 0
err = fileOpOn(t, linux.AT_FDCWD, path, resolveSymlink, func(_ *fs.Dirent, d *fs.Dirent, _ uint) error {
if dirPath && !fs.IsDir(d.Inode.StableAttr) {
return syserror.ENOTDIR
}
- n, value, err := getXattr(t, d, nameAddr, size)
- valueLen = n
- if err != nil {
- return err
- }
-
- _, err = t.CopyOutBytes(valueAddr, []byte(value))
+ n, err = getXattr(t, d, nameAddr, valueAddr, size)
return err
})
if err != nil {
return 0, nil, err
}
- return uintptr(valueLen), nil, nil
+
+ return uintptr(n), nil, nil
}
// getXattr implements getxattr(2) from the given *fs.Dirent.
-func getXattr(t *kernel.Task, d *fs.Dirent, nameAddr usermem.Addr, size uint64) (int, string, error) {
- if err := checkXattrPermissions(t, d.Inode, fs.PermMask{Read: true}); err != nil {
- return 0, "", err
- }
-
+func getXattr(t *kernel.Task, d *fs.Dirent, nameAddr, valueAddr usermem.Addr, size uint64) (int, error) {
name, err := copyInXattrName(t, nameAddr)
if err != nil {
- return 0, "", err
+ return 0, err
+ }
+
+ if err := checkXattrPermissions(t, d.Inode, fs.PermMask{Read: true}); err != nil {
+ return 0, err
}
// TODO(b/148380782): Support xattrs in namespaces other than "user".
if !strings.HasPrefix(name, linux.XATTR_USER_PREFIX) {
- return 0, "", syserror.EOPNOTSUPP
+ return 0, syserror.EOPNOTSUPP
}
// If getxattr(2) is called with size 0, the size of the value will be
@@ -118,18 +110,22 @@ func getXattr(t *kernel.Task, d *fs.Dirent, nameAddr usermem.Addr, size uint64)
value, err := d.Inode.GetXattr(t, name, requestedSize)
if err != nil {
- return 0, "", err
+ return 0, err
}
n := len(value)
if uint64(n) > requestedSize {
- return 0, "", syserror.ERANGE
+ return 0, syserror.ERANGE
}
// Don't copy out the attribute value if size is 0.
if size == 0 {
- return n, "", nil
+ return n, nil
+ }
+
+ if _, err = t.CopyOutBytes(valueAddr, []byte(value)); err != nil {
+ return 0, err
}
- return n, value, nil
+ return n, nil
}
// SetXattr implements linux syscall setxattr(2).