From 932efbd4593fe6be6c86f0dafeaea32910b7c246 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 14 Oct 2018 20:11:49 +0200 Subject: fusefrontend: make openBackingDir() symlink-safe openBackingDir() used encryptPath(), which is not symlink-safe itself. Drop encryptPath() and implement our own directory walk. Adds three seconds to untar and two seconds to rm: $ ./benchmark.bash Testing gocryptfs at /tmp/benchmark.bash.MzG: gocryptfs v1.6-36-g8fb3c2f-dirty; go-fuse v20170619-66-g6df8ddc; 2018-10-14 go1.11 WRITE: 262144000 bytes (262 MB, 250 MiB) copied, 1.25078 s, 210 MB/s READ: 262144000 bytes (262 MB, 250 MiB) copied, 1.0318 s, 254 MB/s UNTAR: 20.941 MD5: 11.568 LS: 1.638 RM: 5.337 --- internal/fusefrontend/names_test.go | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 internal/fusefrontend/names_test.go (limited to 'internal/fusefrontend/names_test.go') diff --git a/internal/fusefrontend/names_test.go b/internal/fusefrontend/names_test.go new file mode 100644 index 0000000..8453e52 --- /dev/null +++ b/internal/fusefrontend/names_test.go @@ -0,0 +1,152 @@ +package fusefrontend + +import ( + "strings" + "syscall" + "testing" + + "golang.org/x/sys/unix" + + "github.com/rfjakob/gocryptfs/internal/syscallcompat" + "github.com/rfjakob/gocryptfs/tests/test_helpers" +) + +func TestOpenBackingDir(t *testing.T) { + cipherdir := test_helpers.InitFS(t) + args := Args{ + Cipherdir: cipherdir, + } + fs := newTestFS(args) + + code := fs.Mkdir("dir1", 0700, nil) + if !code.Ok() { + t.Fatal(code) + } + code = fs.Mkdir("dir1/dir2", 0700, nil) + if !code.Ok() { + t.Fatal(code) + } + + dirfd, cName, err := fs.openBackingDir("") + if err != nil { + t.Fatal(err) + } + if cName != "." { + t.Fatal("cName should be .") + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + err = syscallcompat.Faccessat(dirfd, ".", unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) + + dirfd, cName, err = fs.openBackingDir("dir1") + if err != nil { + t.Fatal(err) + } + if cName == "" { + t.Fatal("cName should not be empty") + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) + + dirfd, cName, err = fs.openBackingDir("dir1/dir2") + if err != nil { + t.Fatal(err) + } + if cName == "" { + t.Fatal("cName should not be empty") + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) + + n255 := strings.Repeat("n", 255) + path := "dir1/" + n255 + fs.Mkdir(path, 0700, nil) + dirfd, cName, err = fs.openBackingDir(path) + if err != nil { + t.Fatal(err) + } + if cName == "" { + t.Fatal("cName should not be empty") + } + if len(cName) >= 255 { + t.Fatalf("cName is too long: %q", cName) + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) +} + +func TestOpenBackingDirPlaintextNames(t *testing.T) { + cipherdir := test_helpers.InitFS(t, "-plaintextnames") + args := Args{ + Cipherdir: cipherdir, + PlaintextNames: true, + } + fs := newTestFS(args) + + code := fs.Mkdir("dir1", 0700, nil) + if !code.Ok() { + t.Fatal(code) + } + code = fs.Mkdir("dir1/dir2", 0700, nil) + if !code.Ok() { + t.Fatal(code) + } + + dirfd, cName, err := fs.openBackingDir("") + if err != nil { + t.Fatal(err) + } + if cName != "." { + t.Fatal("cName should be .") + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + err = syscallcompat.Faccessat(dirfd, ".", unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) + + dirfd, cName, err = fs.openBackingDir("dir1") + if err != nil { + t.Fatal(err) + } + if cName != "dir1" { + t.Fatalf("wrong cName: %q", cName) + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) + + dirfd, cName, err = fs.openBackingDir("dir1/dir2") + if err != nil { + t.Fatal(err) + } + if cName != "dir2" { + t.Fatalf("wrong cName: %q", cName) + } + err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) + if err != nil { + t.Error(err) + } + syscall.Close(dirfd) +} -- cgit v1.2.3