diff options
Diffstat (limited to 'internal/fusefrontend/xattr_linux.go')
-rw-r--r-- | internal/fusefrontend/xattr_linux.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/fusefrontend/xattr_linux.go b/internal/fusefrontend/xattr_linux.go index fd3b7e5..3a64412 100644 --- a/internal/fusefrontend/xattr_linux.go +++ b/internal/fusefrontend/xattr_linux.go @@ -4,7 +4,15 @@ package fusefrontend import ( + "fmt" "strings" + "syscall" + + "golang.org/x/sys/unix" + + "github.com/hanwen/go-fuse/fuse" + + "github.com/rfjakob/gocryptfs/internal/syscallcompat" ) // Only allow the "user" namespace, block "trusted" and "security", as @@ -19,3 +27,57 @@ func disallowedXAttrName(attr string) bool { func filterXattrSetFlags(flags int) int { return flags } + +func (fs *FS) getXAttr(relPath string, cAttr string, context *fuse.Context) ([]byte, fuse.Status) { + dirfd, cName, err := fs.openBackingDir(relPath) + if err != nil { + return nil, fuse.ToStatus(err) + } + defer syscall.Close(dirfd) + + procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) + cData, err := syscallcompat.Lgetxattr(procPath, cAttr) + if err != nil { + return nil, fuse.ToStatus(err) + } + return cData, fuse.OK +} + +func (fs *FS) setXAttr(relPath string, cAttr string, cData []byte, flags int, context *fuse.Context) fuse.Status { + dirfd, cName, err := fs.openBackingDir(relPath) + if err != nil { + return fuse.ToStatus(err) + } + defer syscall.Close(dirfd) + + procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) + err = unix.Lsetxattr(procPath, cAttr, cData, flags) + return fuse.ToStatus(err) +} + +func (fs *FS) removeXAttr(relPath string, cAttr string, context *fuse.Context) fuse.Status { + dirfd, cName, err := fs.openBackingDir(relPath) + if err != nil { + return fuse.ToStatus(err) + } + defer syscall.Close(dirfd) + + procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) + err = unix.Lremovexattr(procPath, cAttr) + return fuse.ToStatus(err) +} + +func (fs *FS) listXAttr(relPath string, context *fuse.Context) ([]string, fuse.Status) { + dirfd, cName, err := fs.openBackingDir(relPath) + if err != nil { + return nil, fuse.ToStatus(err) + } + defer syscall.Close(dirfd) + + procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) + cNames, err := syscallcompat.Llistxattr(procPath) + if err != nil { + return nil, fuse.ToStatus(err) + } + return cNames, fuse.OK +} |