diff options
| author | Jakob Unterwurzacher | 2018-09-30 19:33:52 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2019-01-01 16:24:09 +0100 | 
| commit | ed6ed513d7f06178c0de02e8a372c33fe8f842f1 (patch) | |
| tree | 2659e6851bffb8e6fb5b5da55c84926fe336947e | |
| parent | 545a03da241ad9e2094b45af8202a9d131bfe6ba (diff) | |
fusefrontend: make Access() symlink-safe.
Make Access() symlink-safe through use of faccessat.
| -rw-r--r-- | internal/fusefrontend/fs.go | 14 | ||||
| -rw-r--r-- | tests/matrix/matrix_test.go | 27 | 
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") +	} +} | 
