fusefrontend_reverse: secure Open against symlink races

...using the new syscallcompat.OpenNofollow helper.

This change secures Open() against symlink race attacks
as described in https://github.com/rfjakob/gocryptfs/issues/165
This commit is contained in:
Jakob Unterwurzacher 2017-12-02 21:01:47 +01:00
parent 91e042e2ba
commit 316b916358
2 changed files with 10 additions and 6 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/rfjakob/gocryptfs/internal/contentenc"
"github.com/rfjakob/gocryptfs/internal/pathiv"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@ -32,19 +33,22 @@ type reverseFile struct {
var inodeTable syncmap.Map
func (rfs *ReverseFS) newFile(relPath string, flags uint32) (nodefs.File, fuse.Status) {
absPath, err := rfs.abs(rfs.decryptPath(relPath))
// newFile decrypts and opens the path "relPath" and returns a reverseFile
// object. The backing file descriptor is always read-only.
func (rfs *ReverseFS) newFile(relPath string) (*reverseFile, fuse.Status) {
pRelPath, err := rfs.decryptPath(relPath)
if err != nil {
return nil, fuse.ToStatus(err)
}
fd, err := os.OpenFile(absPath, int(flags), 0666)
fd, err := syscallcompat.OpenNofollow(rfs.args.Cipherdir, pRelPath, syscall.O_RDONLY, 0)
if err != nil {
return nil, fuse.ToStatus(err)
}
var st syscall.Stat_t
err = syscall.Fstat(int(fd.Fd()), &st)
err = syscall.Fstat(fd, &st)
if err != nil {
tlog.Warn.Printf("newFile: Fstat error: %v", err)
syscall.Close(fd)
return nil, fuse.ToStatus(err)
}
// See if we have that inode number already in the table
@ -76,7 +80,7 @@ func (rfs *ReverseFS) newFile(relPath string, flags uint32) (nodefs.File, fuse.S
}
return &reverseFile{
File: nodefs.NewDefaultFile(),
fd: fd,
fd: os.NewFile(uintptr(fd), pRelPath),
header: header,
block0IV: derivedIVs.Block0IV,
contentEnc: rfs.contentEnc,

View File

@ -218,7 +218,7 @@ func (rfs *ReverseFS) Open(relPath string, flags uint32, context *fuse.Context)
if rfs.isNameFile(relPath) {
return rfs.newNameFile(relPath)
}
return rfs.newFile(relPath, flags)
return rfs.newFile(relPath)
}
func (rfs *ReverseFS) openDirPlaintextnames(relPath string, entries []fuse.DirEntry) ([]fuse.DirEntry, fuse.Status) {