summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/names.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/fusefrontend/names.go')
-rw-r--r--internal/fusefrontend/names.go16
1 files changed, 10 insertions, 6 deletions
diff --git a/internal/fusefrontend/names.go b/internal/fusefrontend/names.go
index 9be2623..d7fbdce 100644
--- a/internal/fusefrontend/names.go
+++ b/internal/fusefrontend/names.go
@@ -7,6 +7,7 @@ import (
"path/filepath"
"github.com/rfjakob/gocryptfs/internal/configfile"
+ "github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@@ -40,18 +41,21 @@ func (fs *FS) getBackingPath(relPath string) (string, error) {
return cAbsPath, nil
}
-// openBackingPath - get the absolute encrypted path of the backing file
-// and open the corresponding directory
-func (fs *FS) openBackingPath(relPath string) (*os.File, string, error) {
- cPath, err := fs.getBackingPath(relPath)
+// openBackingDir opens the parent ciphertext directory of plaintext path
+// "relPath" and returns the dirfd and the encrypted basename.
+// The caller should then use Openat(dirfd, cName, ...) and friends.
+// openBackingDir is secure against symlink races.
+func (fs *FS) openBackingDir(relPath string) (*os.File, string, error) {
+ cRelPath, err := fs.encryptPath(relPath)
if err != nil {
return nil, "", err
}
- dirfd, err := os.Open(filepath.Dir(cPath))
+ // Open parent dir
+ dirfd, err := syscallcompat.OpenDirNofollow(fs.args.Cipherdir, filepath.Dir(cRelPath))
if err != nil {
return nil, "", err
}
- return dirfd, filepath.Base(cPath), nil
+ return os.NewFile(uintptr(dirfd), cRelPath), filepath.Base(cRelPath), nil
}
// encryptPath - encrypt relative plaintext path