Flag -zerodiriv to create all diriv as all zero byte files
This commit is contained in:
parent
02c91d73ce
commit
8f94083a21
@ -545,6 +545,11 @@ useful in regression testing.
|
||||
|
||||
Applies to: all actions.
|
||||
|
||||
#### -zerodiriv
|
||||
Create diriv as all-zero files
|
||||
|
||||
Applies to: all actions without `-plaintextnames`.
|
||||
|
||||
#### \-\-
|
||||
Stop option parsing. Helpful when CIPHERDIR may start with a
|
||||
dash "-".
|
||||
|
@ -30,7 +30,7 @@ type argContainer struct {
|
||||
plaintextnames, quiet, nosyslog, wpanic,
|
||||
longnames, allow_other, reverse, aessiv, nonempty, raw64,
|
||||
noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info,
|
||||
sharedstorage, devrandom, fsck, one_file_system bool
|
||||
sharedstorage, devrandom, fsck, one_file_system, zerodiriv bool
|
||||
// Mount options with opposites
|
||||
dev, nodev, suid, nosuid, exec, noexec, rw, ro, kernel_cache, acl bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile,
|
||||
@ -179,6 +179,7 @@ func parseCliOpts(osArgs []string) (args argContainer) {
|
||||
flagSet.BoolVar(&args.devrandom, "devrandom", false, "Use /dev/random for generating master key")
|
||||
flagSet.BoolVar(&args.fsck, "fsck", false, "Run a filesystem check on CIPHERDIR")
|
||||
flagSet.BoolVar(&args.one_file_system, "one-file-system", false, "Don't cross filesystem boundaries")
|
||||
flagSet.BoolVar(&args.zerodiriv, "zerodiriv", false, "Create diriv as all-zero files")
|
||||
|
||||
// Mount options with opposites
|
||||
flagSet.BoolVar(&args.dev, "dev", false, "Allow device files")
|
||||
|
@ -103,7 +103,7 @@ func initDir(args *argContainer) {
|
||||
// Open cipherdir (following symlinks)
|
||||
dirfd, err := syscall.Open(args.cipherdir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0)
|
||||
if err == nil {
|
||||
err = nametransform.WriteDirIVAt(dirfd)
|
||||
err = nametransform.WriteDirIVAt(dirfd, !args.zerodiriv)
|
||||
syscall.Close(dirfd)
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -53,4 +53,6 @@ type Args struct {
|
||||
// like rsync's `--one-file-system` does.
|
||||
// Only applicable to reverse mode.
|
||||
OneFileSystem bool
|
||||
// ZeroDirIV creates diriv files as all-zero files
|
||||
ZeroDirIV bool
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ func haveDsstore(entries []fuse.DirEntry) bool {
|
||||
// should be a handle to the parent directory, cName is the name of the new
|
||||
// directory and mode specifies the access permissions to use.
|
||||
func (n *Node) mkdirWithIv(dirfd int, cName string, mode uint32, context *fuse.Context) error {
|
||||
|
||||
rn := n.rootNode()
|
||||
// Between the creation of the directory and the creation of gocryptfs.diriv
|
||||
// the directory is inconsistent. Take the lock to prevent other readers
|
||||
@ -48,7 +49,7 @@ func (n *Node) mkdirWithIv(dirfd int, cName string, mode uint32, context *fuse.C
|
||||
dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_DIRECTORY|syscall.O_NOFOLLOW|syscallcompat.O_PATH, 0)
|
||||
if err == nil {
|
||||
// Create gocryptfs.diriv
|
||||
err = nametransform.WriteDirIVAt(dirfd2)
|
||||
err = nametransform.WriteDirIVAt(dirfd2, !rn.args.ZeroDirIV)
|
||||
syscall.Close(dirfd2)
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nametransform
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -34,9 +33,6 @@ func ReadDirIVAt(dirfd int) (iv []byte, err error) {
|
||||
return fdReadDirIV(fd)
|
||||
}
|
||||
|
||||
// allZeroDirIV is preallocated to quickly check if the data read from disk is all zero
|
||||
var allZeroDirIV = make([]byte, DirIVLen)
|
||||
|
||||
// fdReadDirIV reads and verifies the DirIV from an opened gocryptfs.diriv file.
|
||||
func fdReadDirIV(fd *os.File) (iv []byte, err error) {
|
||||
// We want to detect if the file is bigger than DirIVLen, so
|
||||
@ -50,9 +46,6 @@ func fdReadDirIV(fd *os.File) (iv []byte, err error) {
|
||||
if len(iv) != DirIVLen {
|
||||
return nil, fmt.Errorf("wanted %d bytes, got %d", DirIVLen, len(iv))
|
||||
}
|
||||
if bytes.Equal(iv, allZeroDirIV) {
|
||||
return nil, fmt.Errorf("diriv is all-zero")
|
||||
}
|
||||
return iv, nil
|
||||
}
|
||||
|
||||
@ -60,8 +53,13 @@ func fdReadDirIV(fd *os.File) (iv []byte, err error) {
|
||||
// "dirfd". On error we try to delete the incomplete file.
|
||||
// This function is exported because it is used from fusefrontend, main,
|
||||
// and also the automated tests.
|
||||
func WriteDirIVAt(dirfd int) error {
|
||||
iv := cryptocore.RandBytes(DirIVLen)
|
||||
func WriteDirIVAt(dirfd int, randomInitialization bool) error {
|
||||
var iv []byte
|
||||
if randomInitialization {
|
||||
iv = cryptocore.RandBytes(DirIVLen)
|
||||
} else {
|
||||
iv = make([]byte, DirIVLen)
|
||||
}
|
||||
// 0400 permissions: gocryptfs.diriv should never be modified after creation.
|
||||
// Don't use "ioutil.WriteFile", it causes trouble on NFS:
|
||||
// https://github.com/rfjakob/gocryptfs/commit/7d38f80a78644c8ec4900cc990bfb894387112ed
|
||||
|
1
mount.go
1
mount.go
@ -276,6 +276,7 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
|
||||
KernelCache: args.kernel_cache,
|
||||
SharedStorage: args.sharedstorage,
|
||||
OneFileSystem: args.one_file_system,
|
||||
ZeroDirIV: args.zerodiriv,
|
||||
}
|
||||
// confFile is nil when "-zerokey" or "-masterkey" was used
|
||||
if confFile != nil {
|
||||
|
@ -110,7 +110,7 @@ func ResetTmpDir(createDirIV bool) {
|
||||
// Open cipherdir (following symlinks)
|
||||
dirfd, err := syscall.Open(DefaultCipherDir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0)
|
||||
if err == nil {
|
||||
err = nametransform.WriteDirIVAt(dirfd)
|
||||
err = nametransform.WriteDirIVAt(dirfd, true)
|
||||
syscall.Close(dirfd)
|
||||
}
|
||||
if err != nil {
|
||||
|
85
tests/zerodiriv/zerodiriv_test.go
Normal file
85
tests/zerodiriv/zerodiriv_test.go
Normal file
@ -0,0 +1,85 @@
|
||||
package zerodiriv
|
||||
|
||||
// integration tests that target zerodiriv specifically
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/rfjakob/gocryptfs/tests/test_helpers"
|
||||
)
|
||||
|
||||
var cDir string
|
||||
var pDir string
|
||||
|
||||
var testPw = []byte("test")
|
||||
|
||||
// Create and mount "-zerodiriv" fs
|
||||
func TestMain(m *testing.M) {
|
||||
cDir = test_helpers.InitFS(nil, "-zerodiriv")
|
||||
pDir = cDir + ".mnt"
|
||||
test_helpers.MountOrExit(cDir, pDir, "-zerodiriv", "-extpass", "echo test")
|
||||
r := m.Run()
|
||||
test_helpers.UnmountPanic(pDir)
|
||||
os.Exit(r)
|
||||
}
|
||||
|
||||
// diriv should be all-zero on newly created dirs
|
||||
func TestZeroDirIV(t *testing.T) {
|
||||
// Create /dir1, move it and create it again
|
||||
var dirPath = pDir+"/dir1"
|
||||
var err = os.Mkdir(dirPath, 0777)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = os.Rename(dirPath, dirPath + ".bak")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = os.Mkdir(dirPath, 0777)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
var matches []string
|
||||
matches, err = filepath.Glob(cDir+"/*/gocryptfs.diriv")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// The contents of the both diriv files must be the same
|
||||
var diriv0 []byte
|
||||
diriv0, err = ioutil.ReadFile(matches[0])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var diriv1 []byte
|
||||
diriv1, err = ioutil.ReadFile(matches[1])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !bytes.Equal(diriv0, diriv1) {
|
||||
t.Errorf("both dirivs should have the same value")
|
||||
}
|
||||
// And equal to zero
|
||||
zerodiriv := make([]byte, len(diriv0))
|
||||
if !bytes.Equal(diriv0, zerodiriv) {
|
||||
t.Errorf("both dirivs should be all-zero")
|
||||
}
|
||||
}
|
||||
|
||||
// root diriv should be all-zero
|
||||
func TestZeroRootDirIV(t *testing.T) {
|
||||
// The contents of the diriv file must be zero
|
||||
diriv, err := ioutil.ReadFile(cDir+"/gocryptfs.diriv")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
zerodiriv := make([]byte, len(diriv))
|
||||
if !bytes.Equal(diriv, zerodiriv) {
|
||||
t.Errorf("root diriv should be all-zero")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user