aboutsummaryrefslogtreecommitdiff
path: root/internal/fusefrontend_reverse
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-12-02 21:01:47 +0100
committerJakob Unterwurzacher2017-12-02 21:07:56 +0100
commit316b916358b8830b53fec9e16b325735aa850b14 (patch)
tree624a79c366876531af329e1d38b25102f03f58bc /internal/fusefrontend_reverse
parent91e042e2bafbec3271d8c79005f7dc8229a16a10 (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.go14
-rw-r--r--internal/fusefrontend_reverse/rfs.go2
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) {