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:
parent
91e042e2ba
commit
316b916358
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user