summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-09-30 19:33:52 +0200
committerJakob Unterwurzacher2019-01-01 16:24:09 +0100
commited6ed513d7f06178c0de02e8a372c33fe8f842f1 (patch)
tree2659e6851bffb8e6fb5b5da55c84926fe336947e
parent545a03da241ad9e2094b45af8202a9d131bfe6ba (diff)
fusefrontend: make Access() symlink-safe.
Make Access() symlink-safe through use of faccessat.
-rw-r--r--internal/fusefrontend/fs.go14
-rw-r--r--tests/matrix/matrix_test.go27
2 files changed, 36 insertions, 5 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index c0d6151..d2f4867 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -581,16 +581,20 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code
return fuse.ToStatus(err)
}
-// Access implements pathfs.Filesystem.
-func (fs *FS) Access(path string, mode uint32, context *fuse.Context) (code fuse.Status) {
- if fs.isFiltered(path) {
+// Access - FUSE call. Check if a file can be accessed in the specified mode(s)
+// (read, write, execute).
+//
+// Symlink-safe through use of faccessat.
+func (fs *FS) Access(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) {
+ if fs.isFiltered(relPath) {
return fuse.EPERM
}
- cPath, err := fs.getBackingPath(path)
+ dirfd, cName, err := fs.openBackingDir(relPath)
if err != nil {
return fuse.ToStatus(err)
}
- return fuse.ToStatus(syscall.Access(cPath, mode))
+ err = unix.Faccessat(dirfd, cName, mode, unix.AT_SYMLINK_NOFOLLOW)
+ return fuse.ToStatus(err)
}
// reportMitigatedCorruption is used to report a corruption that was transparently
diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go
index 6ec41bd..8de835f 100644
--- a/tests/matrix/matrix_test.go
+++ b/tests/matrix/matrix_test.go
@@ -23,6 +23,8 @@ import (
"syscall"
"testing"
+ "golang.org/x/sys/unix"
+
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/tests/test_helpers"
@@ -915,3 +917,28 @@ func TestChmod(t *testing.T) {
}
}
}
+
+// Test that access(2) works correctly
+func TestAccess(t *testing.T) {
+ // Note: t.Name() is not available before in Go 1.8
+ tName := "TestAccess"
+ path := test_helpers.DefaultPlainDir + "/" + tName
+ file, err := os.Create(path)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer file.Close()
+
+ err = unix.Access(path, unix.F_OK)
+ if err != nil {
+ t.Error(err)
+ }
+ err = unix.Access(path, unix.R_OK)
+ if err != nil {
+ t.Error(err)
+ }
+ err = unix.Access(path, unix.X_OK)
+ if err == nil {
+ t.Error("X_OK should have failed")
+ }
+}