diff options
Diffstat (limited to 'internal/fusefrontend_reverse')
| -rw-r--r-- | internal/fusefrontend_reverse/node_xattr.go | 11 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/node_xattr_darwin.go | 12 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/node_xattr_linux.go | 10 |
3 files changed, 19 insertions, 14 deletions
diff --git a/internal/fusefrontend_reverse/node_xattr.go b/internal/fusefrontend_reverse/node_xattr.go index f22764a..9e99cfa 100644 --- a/internal/fusefrontend_reverse/node_xattr.go +++ b/internal/fusefrontend_reverse/node_xattr.go @@ -7,6 +7,7 @@ import ( "syscall" "github.com/rfjakob/gocryptfs/v2/internal/pathiv" + "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" ) // We store encrypted xattrs under this prefix plus the base64-encoded @@ -65,10 +66,18 @@ func (n *Node) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errn if rn.args.NoXattr { return 0, 0 } - pNames, errno := n.listXAttr() + // Can use dest as a temporary buffer + sz, errno := n.listXAttr(dest) if errno != 0 { return 0, errno } + // If dest empty, return the required size + if len(dest) == 0 { + // Asssume ciphertext expansion by a factor of 2 + // TODO: double-check max expansion factor + return uint32(sz * 2), 0 + } + pNames := syscallcompat.ParseListxattrBlob(dest[:sz]) var buf bytes.Buffer for _, pName := range pNames { // ACLs are passed through without encryption diff --git a/internal/fusefrontend_reverse/node_xattr_darwin.go b/internal/fusefrontend_reverse/node_xattr_darwin.go index 6816a18..1832f7f 100644 --- a/internal/fusefrontend_reverse/node_xattr_darwin.go +++ b/internal/fusefrontend_reverse/node_xattr_darwin.go @@ -4,6 +4,7 @@ import ( "syscall" "github.com/hanwen/go-fuse/v2/fs" + "golang.org/x/sys/unix" "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" ) @@ -33,7 +34,7 @@ func (n *Node) getXAttr(cAttr string) (out []byte, errno syscall.Errno) { return cData, 0 } -func (n *Node) listXAttr() (out []string, errno syscall.Errno) { +func (n *Node) listXAttr(buf []byte) (sz int, errno syscall.Errno) { d, errno := n.prepareAtSyscall("") if errno != 0 { return @@ -43,13 +44,10 @@ func (n *Node) listXAttr() (out []string, errno syscall.Errno) { // O_NONBLOCK to not block on FIFOs. fd, err := syscallcompat.Openat(d.dirfd, d.pName, syscall.O_RDONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0) if err != nil { - return nil, fs.ToErrno(err) + return 0, fs.ToErrno(err) } defer syscall.Close(fd) - pNames, err := syscallcompat.Flistxattr(fd) - if err != nil { - return nil, fs.ToErrno(err) - } - return pNames, 0 + sz, err = unix.Flistxattr(fd, buf) + return sz, fs.ToErrno(err) } diff --git a/internal/fusefrontend_reverse/node_xattr_linux.go b/internal/fusefrontend_reverse/node_xattr_linux.go index 3c574f5..226ace4 100644 --- a/internal/fusefrontend_reverse/node_xattr_linux.go +++ b/internal/fusefrontend_reverse/node_xattr_linux.go @@ -5,6 +5,7 @@ import ( "syscall" "github.com/hanwen/go-fuse/v2/fs" + "golang.org/x/sys/unix" "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" ) @@ -27,7 +28,7 @@ func (n *Node) getXAttr(cAttr string) (out []byte, errno syscall.Errno) { return pData, 0 } -func (n *Node) listXAttr() (out []string, errno syscall.Errno) { +func (n *Node) listXAttr(buf []byte) (sz int, errno syscall.Errno) { d, errno := n.prepareAtSyscall("") if errno != 0 { return @@ -35,9 +36,6 @@ func (n *Node) listXAttr() (out []string, errno syscall.Errno) { defer syscall.Close(d.dirfd) procPath := fmt.Sprintf("/proc/self/fd/%d/%s", d.dirfd, d.pName) - pNames, err := syscallcompat.Llistxattr(procPath) - if err != nil { - return nil, fs.ToErrno(err) - } - return pNames, 0 + sz, err := unix.Llistxattr(procPath, buf) + return sz, fs.ToErrno(err) } |
