fusefrontend: make Access() symlink-safe.

Make Access() symlink-safe through use of faccessat.
This commit is contained in:
Jakob Unterwurzacher 2018-09-30 19:33:52 +02:00
parent 545a03da24
commit ed6ed513d7
2 changed files with 36 additions and 5 deletions

View File

@ -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

View File

@ -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")
}
}