diff options
author | Jakob Unterwurzacher | 2025-01-18 14:11:51 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2025-01-18 14:13:52 +0100 |
commit | 9eb47cf546d7e2499eab210d70050ef78087475a (patch) | |
tree | 39e74927d89f8d80de46e4edc627e6526a72f2eb /tests | |
parent | c19f986ba09e675a5139b12bcf2687495f2533dd (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).
Diffstat (limited to 'tests')
-rw-r--r-- | tests/reverse/correctness_test.go | 65 |
1 files changed, 65 insertions, 0 deletions
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") + } +} |