diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/fusefrontend/fs.go | 14 | ||||
| -rw-r--r-- | internal/fusefrontend/fs_dir.go | 2 | ||||
| -rw-r--r-- | internal/fusefrontend/names.go | 16 | 
3 files changed, 18 insertions, 14 deletions
| diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 45b5b40..d68939b 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -250,7 +250,7 @@ func (fs *FS) Chmod(path string, mode uint32, context *fuse.Context) (code fuse.  	if fs.isFiltered(path) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(path) +	dirfd, cName, err := fs.openBackingDir(path)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -266,7 +266,7 @@ func (fs *FS) Chown(path string, uid uint32, gid uint32, context *fuse.Context)  	if fs.isFiltered(path) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(path) +	dirfd, cName, err := fs.openBackingDir(path)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -291,7 +291,7 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context)  	if fs.isFiltered(path) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(path) +	dirfd, cName, err := fs.openBackingDir(path)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -409,7 +409,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {  	if fs.isFiltered(path) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(path) +	dirfd, cName, err := fs.openBackingDir(path)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -447,7 +447,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co  	if fs.isFiltered(linkName) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(linkName) +	dirfd, cName, err := fs.openBackingDir(linkName)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -579,12 +579,12 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code  	if fs.isFiltered(newPath) {  		return fuse.EPERM  	} -	oldDirFd, cOldName, err := fs.openBackingPath(oldPath) +	oldDirFd, cOldName, err := fs.openBackingDir(oldPath)  	if err != nil {  		return fuse.ToStatus(err)  	}  	defer oldDirFd.Close() -	newDirFd, cNewName, err := fs.openBackingPath(newPath) +	newDirFd, cNewName, err := fs.openBackingDir(newPath)  	if err != nil {  		return fuse.ToStatus(err)  	} diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go index b7bc790..b9266dd 100644 --- a/internal/fusefrontend/fs_dir.go +++ b/internal/fusefrontend/fs_dir.go @@ -54,7 +54,7 @@ func (fs *FS) Mkdir(newPath string, mode uint32, context *fuse.Context) (code fu  	if fs.isFiltered(newPath) {  		return fuse.EPERM  	} -	dirfd, cName, err := fs.openBackingPath(newPath) +	dirfd, cName, err := fs.openBackingDir(newPath)  	if err != nil {  		return fuse.ToStatus(err)  	} diff --git a/internal/fusefrontend/names.go b/internal/fusefrontend/names.go index 9be2623..d7fbdce 100644 --- a/internal/fusefrontend/names.go +++ b/internal/fusefrontend/names.go @@ -7,6 +7,7 @@ import (  	"path/filepath"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/syscallcompat"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -40,18 +41,21 @@ func (fs *FS) getBackingPath(relPath string) (string, error) {  	return cAbsPath, nil  } -// openBackingPath - get the absolute encrypted path of the backing file -// and open the corresponding directory -func (fs *FS) openBackingPath(relPath string) (*os.File, string, error) { -	cPath, err := fs.getBackingPath(relPath) +// openBackingDir opens the parent ciphertext directory of plaintext path +// "relPath" and returns the dirfd and the encrypted basename. +// The caller should then use Openat(dirfd, cName, ...) and friends. +// openBackingDir is secure against symlink races. +func (fs *FS) openBackingDir(relPath string) (*os.File, string, error) { +	cRelPath, err := fs.encryptPath(relPath)  	if err != nil {  		return nil, "", err  	} -	dirfd, err := os.Open(filepath.Dir(cPath)) +	// Open parent dir +	dirfd, err := syscallcompat.OpenDirNofollow(fs.args.Cipherdir, filepath.Dir(cRelPath))  	if err != nil {  		return nil, "", err  	} -	return dirfd, filepath.Base(cPath), nil +	return os.NewFile(uintptr(dirfd), cRelPath), filepath.Base(cRelPath), nil  }  // encryptPath - encrypt relative plaintext path | 
