summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2025-01-18 14:11:51 +0100
committerJakob Unterwurzacher2025-01-18 14:13:52 +0100
commit9eb47cf546d7e2499eab210d70050ef78087475a (patch)
tree39e74927d89f8d80de46e4edc627e6526a72f2eb
parentc19f986ba09e675a5139b12bcf2687495f2533dd (diff)
reverse: advance mtime & ctime for virtual files by 10 seconds
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).
-rw-r--r--internal/fusefrontend_reverse/virtualnode.go9
-rw-r--r--tests/reverse/correctness_test.go65
2 files changed, 74 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/virtualnode.go b/internal/fusefrontend_reverse/virtualnode.go
index 732564a..95e71ab 100644
--- a/internal/fusefrontend_reverse/virtualnode.go
+++ b/internal/fusefrontend_reverse/virtualnode.go
@@ -100,6 +100,15 @@ func (n *Node) newVirtualMemNode(content []byte, parentStat *syscall.Stat_t, ino
st.Nlink = 1
var a fuse.Attr
a.FromStat(st)
+ // 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).
+ a.Mtime += 10
+ a.Ctime += 10
if rn.args.ForceOwner != nil {
a.Owner = *rn.args.ForceOwner
}
diff --git a/tests/reverse/correctness_test.go b/tests/reverse/correctness_test.go
index 8f051d0..c93c32a 100644
--- a/tests/reverse/correctness_test.go
+++ b/tests/reverse/correctness_test.go
@@ -363,3 +363,68 @@ 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)
+ }
+ var long_stat syscall.Stat_t
+ if err := syscall.Stat(long, &long_stat); err != nil {
+ t.Fatal(err)
+ }
+
+ var workdirA_stat syscall.Stat_t
+ if err := syscall.Stat(workdirA, &workdirA_stat); 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)
+ }
+ var name_stat syscall.Stat_t
+ if err := syscall.Stat(matches[0], &name_stat); err != nil {
+ t.Fatal(err)
+ }
+ if name_stat.Mtim.Sec != long_stat.Mtim.Sec+10 {
+ t.Errorf(".name file should show mtime+10")
+ }
+ if name_stat.Ctim.Sec != long_stat.Ctim.Sec+10 {
+ t.Errorf(".name file should show ctime+10")
+ }
+
+ if deterministic_names {
+ // No gocryptfs.diriv
+ return
+ }
+
+ // Check gocryptfs.diriv
+ var diriv_stat syscall.Stat_t
+ if err := syscall.Stat(workdirB+"/gocryptfs.diriv", &diriv_stat); err != nil {
+ t.Fatal(err)
+ }
+ if diriv_stat.Mtim.Sec != workdirA_stat.Mtim.Sec+10 {
+ t.Errorf("diriv file should show mtime+10")
+ }
+ if diriv_stat.Ctim.Sec != workdirA_stat.Ctim.Sec+10 {
+ t.Errorf("diriv file should show ctime+10")
+ }
+}