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/contentenc"
"github.com/rfjakob/gocryptfs/internal/pathiv" "github.com/rfjakob/gocryptfs/internal/pathiv"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog" "github.com/rfjakob/gocryptfs/internal/tlog"
) )
@ -32,19 +33,22 @@ type reverseFile struct {
var inodeTable syncmap.Map var inodeTable syncmap.Map
func (rfs *ReverseFS) newFile(relPath string, flags uint32) (nodefs.File, fuse.Status) { // newFile decrypts and opens the path "relPath" and returns a reverseFile
absPath, err := rfs.abs(rfs.decryptPath(relPath)) // 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 { if err != nil {
return nil, fuse.ToStatus(err) 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 { if err != nil {
return nil, fuse.ToStatus(err) return nil, fuse.ToStatus(err)
} }
var st syscall.Stat_t var st syscall.Stat_t
err = syscall.Fstat(int(fd.Fd()), &st) err = syscall.Fstat(fd, &st)
if err != nil { if err != nil {
tlog.Warn.Printf("newFile: Fstat error: %v", err) tlog.Warn.Printf("newFile: Fstat error: %v", err)
syscall.Close(fd)
return nil, fuse.ToStatus(err) return nil, fuse.ToStatus(err)
} }
// See if we have that inode number already in the table // 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{ return &reverseFile{
File: nodefs.NewDefaultFile(), File: nodefs.NewDefaultFile(),
fd: fd, fd: os.NewFile(uintptr(fd), pRelPath),
header: header, header: header,
block0IV: derivedIVs.Block0IV, block0IV: derivedIVs.Block0IV,
contentEnc: rfs.contentEnc, contentEnc: rfs.contentEnc,

View File

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