From 810d2a8b474e0102a8be3f6b00a3855e182dbd43 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 11 Nov 2018 17:57:24 +0100 Subject: fusefrontend: make SetXAttr() symlink-safe on Linux Uses the /proc/self/fd trick. --- internal/fusefrontend/xattr_linux.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'internal/fusefrontend/xattr_linux.go') diff --git a/internal/fusefrontend/xattr_linux.go b/internal/fusefrontend/xattr_linux.go index 5a189db..659657d 100644 --- a/internal/fusefrontend/xattr_linux.go +++ b/internal/fusefrontend/xattr_linux.go @@ -28,6 +28,7 @@ func filterXattrSetFlags(flags int) int { return flags } +// procFd returns the path to file descriptor "fd" in /proc/self/fd. func procFd(fd int) string { return fmt.Sprintf("/proc/self/fd/%d", fd) } @@ -51,10 +52,10 @@ func (fs *FS) getFileFd(relPath string, context *fuse.Context) (*File, int, fuse return file, file.intFd(), fuse.OK } -// getXattr - read encrypted xattr name "cAttr" from the file at relative +// getXattr - read encrypted xattr name "cAttr" from relative // plaintext path "relPath". Returns the encrypted xattr value. // -// This function is symlink-safe. +// This function is symlink-safe by using /proc/self/fd. func (fs *FS) getXattr(relPath string, cAttr string, context *fuse.Context) ([]byte, fuse.Status) { file, fd, status := fs.getFileFd(relPath, context) if !status.Ok() { @@ -68,3 +69,18 @@ func (fs *FS) getXattr(relPath string, cAttr string, context *fuse.Context) ([]b } return cData, fuse.OK } + +// setXattr - set encrypted xattr name "cAttr" to value "cData" on plaintext +// path "relPath". +// +// This function is symlink-safe by using /proc/self/fd. +func (fs *FS) setXattr(relPath string, cAttr string, cData []byte, flags int, context *fuse.Context) fuse.Status { + file, fd, status := fs.getFileFd(relPath, context) + if !status.Ok() { + return status + } + defer file.Release() + + err := xattr.SetWithFlags(procFd(fd), cAttr, cData, flags) + return unpackXattrErr(err) +} -- cgit v1.2.3