diff options
author | Jakob Unterwurzacher | 2019-01-02 20:48:46 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2019-01-02 20:48:46 +0100 |
commit | b214be5e3f76dd17efc9832131f4a7e0414b4cea (patch) | |
tree | 511e71e93a919f7319df7ee774eaa5c2e1fd974c /internal/syscallcompat/sys_common.go | |
parent | d269c28d169cdf071acf57d283b756cde2b6437f (diff) |
fusefrontend: xattr: fix operations on files without read permissions
* listxattr is fixed via the /proc/self/fd trick
* setxattr,removexattr are fixed by opening the file O_WRONLY
Fixes https://github.com/rfjakob/gocryptfs/issues/308
Diffstat (limited to 'internal/syscallcompat/sys_common.go')
-rw-r--r-- | internal/syscallcompat/sys_common.go | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/internal/syscallcompat/sys_common.go b/internal/syscallcompat/sys_common.go index 3a0d5a1..4ce0208 100644 --- a/internal/syscallcompat/sys_common.go +++ b/internal/syscallcompat/sys_common.go @@ -64,7 +64,7 @@ func Fgetxattr(fd int, attr string) (val []byte, err error) { // only happen on MacOS). // // See https://github.com/pkg/xattr for a smarter solution. - // TODO: be smarter? + // TODO: smarter buffer sizing? buf := make([]byte, XATTR_BUFSZ) sz, err := unix.Fgetxattr(fd, attr, buf) if err == syscall.ERANGE { @@ -84,11 +84,11 @@ func Fgetxattr(fd int, attr string) (val []byte, err error) { return val, nil } -// Flistxattr is a wrapper unix.Flistxattr that handles buffer sizing and +// 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) { // See the buffer sizing comments in Fgetxattr. - // TODO: be smarter? + // TODO: smarter buffer sizing? buf := make([]byte, XATTR_BUFSZ) sz, err := unix.Flistxattr(fd, buf) if err == syscall.ERANGE { @@ -101,7 +101,31 @@ func Flistxattr(fd int) (attrs []string, err error) { if sz >= XATTR_SIZE_MAX { return nil, syscall.EOVERFLOW } - buf = buf[:sz] + attrs = parseListxattrBlob(buf[:sz]) + return attrs, nil +} + +// Llistxattr is a wrapper for unix.Llistxattr that handles buffer sizing and +// parsing the returned blob to a string slice. +func Llistxattr(path string) (attrs []string, err error) { + // TODO: smarter buffer sizing? + buf := make([]byte, XATTR_BUFSZ) + sz, err := unix.Llistxattr(path, 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 + } + attrs = parseListxattrBlob(buf[:sz]) + return attrs, nil +} + +func parseListxattrBlob(buf []byte) (attrs []string) { parts := bytes.Split(buf, []byte{0}) for _, part := range parts { if len(part) == 0 { @@ -110,5 +134,5 @@ func Flistxattr(fd int) (attrs []string, err error) { } attrs = append(attrs, string(part)) } - return attrs, nil + return attrs } |