aboutsummaryrefslogtreecommitdiff
path: root/internal/syscallcompat/sys_common.go
diff options
context:
space:
mode:
authorSebastian Lackner2019-01-05 04:33:50 +0100
committerrfjakob2019-01-05 12:34:40 +0100
commit5055f39bd534b1f13257f95ffdc28575b9b2e3ed (patch)
treeeb3f1c960d9a51a6301dc6586bdab10d579b715b /internal/syscallcompat/sys_common.go
parentf17721c364a522f87b3351a73676405d44b955f6 (diff)
fusefrontend: Allow to set/remove xattr on directory without read permission.
Setting/removing extended attributes on directories was partially fixed with commit eff35e60b63331e3e10f921792baa10b236a721d. However, on most file systems it is also possible to do these operations without read access (see tests). Since we cannot open a write-access fd to a directory, we have to use the /proc/self/fd trick (already used for ListXAttr) for the other operations aswell. For simplicity, let's separate the Linux and Darwin code again (basically revert commit f320b76fd189a363a34bffe981aa67ab97df3362), and always use the /proc/self/fd trick on Linux. On Darwin we use the best-effort approach with openBackingFile() as a fallback. More discussion about the available options is available in https://github.com/rfjakob/gocryptfs/issues/308.
Diffstat (limited to 'internal/syscallcompat/sys_common.go')
-rw-r--r--internal/syscallcompat/sys_common.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/internal/syscallcompat/sys_common.go b/internal/syscallcompat/sys_common.go
index 4ce0208..a1aa66d 100644
--- a/internal/syscallcompat/sys_common.go
+++ b/internal/syscallcompat/sys_common.go
@@ -84,6 +84,29 @@ func Fgetxattr(fd int, attr string) (val []byte, err error) {
return val, nil
}
+// Lgetxattr is a wrapper around unix.Lgetxattr that handles the buffer sizing.
+func Lgetxattr(path string, attr string) (val []byte, err error) {
+ // See the buffer sizing comments in Fgetxattr.
+ // TODO: smarter buffer sizing?
+ buf := make([]byte, XATTR_BUFSZ)
+ sz, err := unix.Lgetxattr(path, attr, buf)
+ if err == syscall.ERANGE {
+ // Do NOT return ERANGE - the user might retry ad inifinitum!
+ return nil, syscall.EOVERFLOW
+ }
+ if err != nil {
+ return nil, err
+ }
+ if sz >= XATTR_SIZE_MAX {
+ return nil, syscall.EOVERFLOW
+ }
+ // Copy only the actually used bytes to a new (smaller) buffer
+ // so "buf" never leaves the function and can be allocated on the stack.
+ val = make([]byte, sz)
+ copy(val, buf)
+ return val, nil
+}
+
// Flistxattr is a wrapper for unix.Flistxattr that handles buffer sizing and
// parsing the returned blob to a string slice.
func Flistxattr(fd int) (attrs []string, err error) {