Skip to content

Commit

Permalink
fusefronted: report plaintext size on symlink creation
Browse files Browse the repository at this point in the history
gocryptfs 2.0 introduced the regression that the size
reported at symlink creation was the ciphertext size,
which is wrong.

Report the plaintext size.

Fixes #574
  • Loading branch information
rfjakob committed Jun 6, 2021
1 parent 6910f86 commit 17f859d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
3 changes: 3 additions & 0 deletions internal/fusefrontend/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry
errno = fs.ToErrno(err)
return
}
// Report the plaintext size, not the encrypted blob size
st.Size = int64(len(target))

inode = n.newChild(ctx, st, out)
return inode, 0
}
Expand Down
2 changes: 2 additions & 0 deletions internal/fusefrontend/node_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ func (n *Node) readlink(dirfd int, cName string) (out []byte, errno syscall.Errn
}

// translateSize translates the ciphertext size in `out` into plaintext size.
// Handles regular files & symlinks (and finds out what is what by looking at
// `out.Mode`).
func (n *Node) translateSize(dirfd int, cName string, out *fuse.Attr) {
if out.IsRegular() {
rn := n.rootNode()
Expand Down
19 changes: 19 additions & 0 deletions tests/matrix/matrix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"math/rand"
"os"
"os/exec"
"path/filepath"
"runtime"
"sync"
"syscall"
Expand Down Expand Up @@ -882,3 +883,21 @@ func TestStatfs(t *testing.T) {
t.Errorf("statfs reports size zero: %#v", st)
}
}

// gocryptfs 2.0 reported the ciphertext size on symlink creation, causing
// confusion: https://github.com/rfjakob/gocryptfs/issues/574
func TestSymlinkSize(t *testing.T) {
p := filepath.Join(test_helpers.DefaultPlainDir, t.Name())
// SYMLINK reports the size to the kernel
if err := syscall.Symlink("foo", p); err != nil {
t.Fatal(err)
}
// Kernel serves us this value from the attr cache
var st syscall.Stat_t
if err := syscall.Lstat(p, &st); err != nil {
t.Fatal(err)
}
if st.Size != 3 {
t.Errorf("wrong size: have %d, want %d", st.Size, 3)
}
}

0 comments on commit 17f859d

Please sign in to comment.