From 17f859d3c409bf2730a47d56979c0700171006b7 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 6 Jun 2021 19:22:16 +0200 Subject: [PATCH] fusefronted: report plaintext size on symlink creation 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 https://github.com/rfjakob/gocryptfs/issues/574 --- internal/fusefrontend/node.go | 3 +++ internal/fusefrontend/node_helpers.go | 2 ++ tests/matrix/matrix_test.go | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go index 657a3bc..8370a22 100644 --- a/internal/fusefrontend/node.go +++ b/internal/fusefrontend/node.go @@ -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 } diff --git a/internal/fusefrontend/node_helpers.go b/internal/fusefrontend/node_helpers.go index 6c30523..b2f1d4a 100644 --- a/internal/fusefrontend/node_helpers.go +++ b/internal/fusefrontend/node_helpers.go @@ -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() diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go index ec4c092..6622213 100644 --- a/tests/matrix/matrix_test.go +++ b/tests/matrix/matrix_test.go @@ -19,6 +19,7 @@ import ( "math/rand" "os" "os/exec" + "path/filepath" "runtime" "sync" "syscall" @@ -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) + } +}