Skip to content

Commit

Permalink
reverse: use incrementing inode number for gocryptfs.longname.*.name …
Browse files Browse the repository at this point in the history
…files

ed0a12b already fixed the kernel side,
now we also want the .name files to NOT appear hardlinked when just
looking at the inode number.

Relates-to: #802
  • Loading branch information
rfjakob committed May 5, 2024
1 parent bbfbf37 commit a385079
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
11 changes: 9 additions & 2 deletions internal/fusefrontend_reverse/virtualnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,15 @@ func (n *Node) newVirtualMemNode(content []byte, parentStat *syscall.Stat_t, ino
// Adjust inode number and size
rn := n.rootNode()
st := parentStat
q := inomap.NewQIno(uint64(st.Dev), inoTag, uint64(st.Ino))
st.Ino = rn.inoMap.Translate(q)
if inoTag == inoTagNameFile {
// No stable mapping for gocryptfs.longname.*.name files, instead use an
// incrementing counter. We don't want two of those files to ever have the
// same inode number, even for hard-linked files.
st.Ino = rn.inoMap.NextSpillIno()
} else {
q := inomap.NewQIno(uint64(st.Dev), inoTag, uint64(st.Ino))
st.Ino = rn.inoMap.Translate(q)
}
st.Size = int64(len(content))
st.Mode = virtualFileMode
st.Nlink = 1
Expand Down
16 changes: 16 additions & 0 deletions tests/reverse/correctness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ func TestSeekData(t *testing.T) {
// gocryptfs.longname.*.name of hardlinked files should not appear hardlinked (as the
// contents are different).
//
// This means that
// 1) They have a different NodeID, hence the kernel knows it's different files
// 2) They have a different inode number, hence userspace knows they are not hard-linked.
//
// https://github.com/rfjakob/gocryptfs/issues/802
func TestHardlinkedLongname(t *testing.T) {
if plaintextnames {
Expand Down Expand Up @@ -335,4 +339,16 @@ func TestHardlinkedLongname(t *testing.T) {
if test_helpers.Md5fn(matches[0]) == test_helpers.Md5fn(matches[1]) {
t.Errorf("Files %q are identical - that's wrong!", matches)
}

var st0 syscall.Stat_t
if err := syscall.Stat(matches[0], &st0); err != nil {
t.Fatal(err)
}
var st1 syscall.Stat_t
if err := syscall.Stat(matches[1], &st1); err != nil {
t.Fatal(err)
}
if st0.Ino == st1.Ino {
t.Errorf("Files %q have the same inode number - that's wrong!", matches)
}
}
4 changes: 2 additions & 2 deletions tests/reverse/inomap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func TestVirtualFileIno(t *testing.T) {
if origInos.child == cipherInos.name {
t.Errorf("name ino collision: %d == %d", origInos.child, cipherInos.name)
}
if origInos.child&mask != cipherInos.name&mask {
t.Errorf("name ino mismatch: %#x vs %#x", origInos.child, cipherInos.name)
if cipherInos.name < 1<<63 {
t.Errorf("name ino should be in spill space, but is actually %#x", cipherInos.name)
}
}

0 comments on commit a385079

Please sign in to comment.