aboutsummaryrefslogtreecommitdiff
path: root/tests/reverse/correctness_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/reverse/correctness_test.go')
-rw-r--r--tests/reverse/correctness_test.go97
1 files changed, 83 insertions, 14 deletions
diff --git a/tests/reverse/correctness_test.go b/tests/reverse/correctness_test.go
index b335456..e4684df 100644
--- a/tests/reverse/correctness_test.go
+++ b/tests/reverse/correctness_test.go
@@ -295,6 +295,23 @@ func TestSeekData(t *testing.T) {
f.Close()
}
+// newWorkdir creates a new empty dir in dirA and returns the full path to it along
+// with the corresponding encrypted path in dirB
+func newWorkdir(t *testing.T) (workdirA, workdirB string) {
+ workdirA = dirA + "/" + t.Name()
+ if err := os.Mkdir(workdirA, 0700); err != nil {
+ t.Fatal(err)
+ }
+ // Find workdir in dirB (=encrypted view)
+ var st syscall.Stat_t
+ if err := syscall.Stat(workdirA, &st); err != nil {
+ t.Fatal(err)
+ }
+ workdirB = dirB + "/" + findIno(dirB, st.Ino)
+ t.Logf("newWorkdir: workdirA=%q workdirB=%q", workdirA, workdirB)
+ return
+}
+
// gocryptfs.longname.*.name of hardlinked files should not appear hardlinked (as the
// contents are different).
//
@@ -308,28 +325,22 @@ func TestHardlinkedLongname(t *testing.T) {
t.Skip()
}
- workdir := dirA + "/" + t.Name()
- if err := os.Mkdir(workdir, 0700); err != nil {
- t.Fatal(err)
- }
- long1 := workdir + "/" + strings.Repeat("x", 200)
+ workdirA, workdirB := newWorkdir(t)
+
+ long1 := workdirA + "/" + strings.Repeat("x", 200)
if err := ioutil.WriteFile(long1, []byte("hello"), 0600); err != nil {
t.Fatal(err)
}
- long2 := workdir + "/" + strings.Repeat("y", 220)
- if err := syscall.Link(long1, long2); err != nil {
+ var long1_stat syscall.Stat_t
+ if err := syscall.Stat(long1, &long1_stat); err != nil {
t.Fatal(err)
}
-
- // Find workdir in encrypted view
- var st syscall.Stat_t
- if err := syscall.Stat(workdir, &st); err != nil {
+ long2 := workdirA + "/" + strings.Repeat("y", 220)
+ if err := syscall.Link(long1, long2); err != nil {
t.Fatal(err)
}
- cWorkdir := dirB + "/" + findIno(dirB, st.Ino)
- t.Logf("workdir=%q cWorkdir=%q", workdir, cWorkdir)
- matches, err := filepath.Glob(cWorkdir + "/gocryptfs.longname.*.name")
+ matches, err := filepath.Glob(workdirB + "/gocryptfs.longname.*.name")
if err != nil {
t.Fatal(err)
}
@@ -352,3 +363,61 @@ func TestHardlinkedLongname(t *testing.T) {
t.Errorf("Files %q have the same inode number - that's wrong!", matches)
}
}
+
+// With inode number reuse and hard links, we could have returned
+// wrong data for gocryptfs.diriv and gocryptfs.xyz.longname files, respectively
+// (https://github.com/rfjakob/gocryptfs/issues/802).
+//
+// Now that this is fixed, ensure that rsync and similar tools pick up the new
+// correct files by advancing mtime and ctime by 10 seconds, which should be more
+// than any filesytems' timestamp granularity (FAT32 has 2 seconds).
+func TestMtimePlus10(t *testing.T) {
+ if plaintextnames {
+ t.Skip("plaintextnames mode does not have virtual files")
+ }
+
+ workdirA, workdirB := newWorkdir(t)
+
+ long := workdirA + "/" + strings.Repeat("x", 200)
+ if err := os.WriteFile(long, nil, 0600); err != nil {
+ t.Fatal(err)
+ }
+ long_stat, err := os.Stat(long)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ workdirA_stat, err := os.Stat(workdirA)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Find and check gocryptfs.longname.*.name
+ matches, err := filepath.Glob(workdirB + "/gocryptfs.longname.*.name")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(matches) != 1 {
+ t.Fatal(matches)
+ }
+ name_stat, err := os.Stat(matches[0])
+ if err != nil {
+ t.Fatal(err)
+ }
+ if name_stat.ModTime().Unix() != long_stat.ModTime().Unix()+10 {
+ t.Errorf(".name file should show mtime+10")
+ }
+
+ // Check gocryptfs.diriv
+ if deterministic_names {
+ // No gocryptfs.diriv
+ return
+ }
+ diriv_stat, err := os.Stat(workdirB + "/gocryptfs.diriv")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diriv_stat.ModTime().Unix() != workdirA_stat.ModTime().Unix()+10 {
+ t.Errorf("diriv file should show mtime+10")
+ }
+}