aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cryptfs/names_diriv.go9
-rw-r--r--pathfs_frontend/fs.go18
-rw-r--r--pathfs_frontend/names.go4
3 files changed, 23 insertions, 8 deletions
diff --git a/cryptfs/names_diriv.go b/cryptfs/names_diriv.go
index c9debab..1415bcb 100644
--- a/cryptfs/names_diriv.go
+++ b/cryptfs/names_diriv.go
@@ -21,6 +21,15 @@ func (be *CryptFS) readDirIV(dir string) (iv []byte, err error) {
return iv, nil
}
+// WriteDirIV - create diriv file inside "dir" (absolute path)
+// This function is exported because it is used from pathfs_frontend
+func (be *CryptFS) WriteDirIV(dir string) error {
+ iv := RandBytes(DIRIV_LEN)
+ file := filepath.Join(dir, DIRIV_FILENAME)
+ // 0444 permissions: the file is not secret but should not be written to
+ return ioutil.WriteFile(file, iv, 0444)
+}
+
// EncryptPathDirIV - encrypt path using CBC with DirIV
func (be *CryptFS) EncryptPathDirIV(plainPath string, rootDir string) (string, error) {
if be.plaintextNames {
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index 48ea4a2..0e0d022 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -5,7 +5,6 @@ import (
"fmt"
"sync"
"syscall"
- "io/ioutil"
"os"
"path/filepath"
"time"
@@ -20,7 +19,11 @@ type FS struct {
*cryptfs.CryptFS
pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
backingDir string // Backing directory, cipherdir
- dirivLock sync.RWMutex // Global lock that is taken if any "gocryptfs.diriv" file is modified
+ // dirIVLock: Lock()ed if any "gocryptfs.diriv" file is modified
+ // Readers must RLock() it to prevent them from seeing intermediate
+ // states
+ dirIVLock sync.RWMutex
+
}
// Encrypted FUSE overlay filesystem
@@ -217,16 +220,15 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
if err != nil {
return fuse.ToStatus(err)
}
- diriv := cryptfs.RandBytes(cryptfs.DIRIV_LEN)
- dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME)
// Create directory
+ fs.dirIVLock.Lock()
+ defer fs.dirIVLock.Unlock()
err = os.Mkdir(encPath, os.FileMode(mode))
if err != nil {
return fuse.ToStatus(err)
}
// Create gocryptfs.diriv inside
- // 0444 permissions: the file is not secret but should not be written to
- err = ioutil.WriteFile(dirivPath, diriv, 0444)
+ err = fs.CryptFS.WriteDirIV(encPath)
if err != nil {
// This should not happen
cryptfs.Warn.Printf("Creating %s in dir %s failed: %v\n", cryptfs.DIRIV_FILENAME, encPath, err)
@@ -282,8 +284,8 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", st.Ino)
tmpDirivPath := filepath.Join(parentDir, tmpName)
cryptfs.Debug.Printf("Rmdir: Renaming %s to %s\n", cryptfs.DIRIV_FILENAME, tmpDirivPath)
- fs.dirivLock.Lock() // directory will be in an inconsistent state after the rename
- defer fs.dirivLock.Unlock()
+ fs.dirIVLock.Lock() // directory will be in an inconsistent state after the rename
+ defer fs.dirIVLock.Unlock()
err = os.Rename(dirivPath, tmpDirivPath)
if err != nil {
cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v\n", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
diff --git a/pathfs_frontend/names.go b/pathfs_frontend/names.go
index 5842d83..9c6e010 100644
--- a/pathfs_frontend/names.go
+++ b/pathfs_frontend/names.go
@@ -3,9 +3,13 @@ package pathfs_frontend
// This file handles filename encryption
func (fs *FS) encryptPath(plainPath string) (string, error) {
+ fs.dirIVLock.RLock()
+ defer fs.dirIVLock.RUnlock()
return fs.CryptFS.EncryptPathDirIV(plainPath, fs.backingDir)
}
func (fs *FS) decryptPath(cipherPath string) (string, error) {
+ fs.dirIVLock.RLock()
+ defer fs.dirIVLock.RUnlock()
return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.backingDir)
}