diff options
author | Jakob Unterwurzacher | 2017-12-02 21:01:47 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2017-12-02 21:07:56 +0100 |
commit | 316b916358b8830b53fec9e16b325735aa850b14 (patch) | |
tree | 624a79c366876531af329e1d38b25102f03f58bc /internal/fusefrontend_reverse | |
parent | 91e042e2bafbec3271d8c79005f7dc8229a16a10 (diff) |
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
Diffstat (limited to 'internal/fusefrontend_reverse')
-rw-r--r-- | internal/fusefrontend_reverse/rfile.go | 14 | ||||
-rw-r--r-- | internal/fusefrontend_reverse/rfs.go | 2 |
2 files changed, 10 insertions, 6 deletions
diff --git a/internal/fusefrontend_reverse/rfile.go b/internal/fusefrontend_reverse/rfile.go index 742d697..c10d341 100644 --- a/internal/fusefrontend_reverse/rfile.go +++ b/internal/fusefrontend_reverse/rfile.go @@ -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, diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go index 8afc270..09ebe9e 100644 --- a/internal/fusefrontend_reverse/rfs.go +++ b/internal/fusefrontend_reverse/rfs.go @@ -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) { |