fusefrontend: make Access() symlink-safe.
Make Access() symlink-safe through use of faccessat.
This commit is contained in:
parent
545a03da24
commit
ed6ed513d7
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user