summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorM. Vefa Bicakci2017-03-07 12:09:09 +0300
committerJakob Unterwurzacher2017-03-07 20:46:58 +0100
commitd48ccb3ddab71773a991b8f1b062901ff5b435b0 (patch)
tree54aab9db59a7d7cc43ca2e1199d6f9aa1ff388c4
parent6e9b6e17c33b4471c30248c11b292468fe4ab912 (diff)
Report correct symbolic link dentry sizes
Prior to this commit, gocryptfs's reverse mode did not report correct directory entry sizes for symbolic links, where the dentry size needs to be the same as the length of a string containing the target path. This commit corrects this issue and adds a test case to verify the correctness of the implementation. This issue was discovered during the use of a strict file copying program on a reverse-mounted gocryptfs file system.
-rw-r--r--internal/fusefrontend_reverse/rfs.go10
-rw-r--r--tests/reverse/correctness_test.go38
l---------tests/reverse/ctlsock_reverse_test_fs/a_symlink1
3 files changed, 49 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go
index f9a2979..a3a3d3b 100644
--- a/internal/fusefrontend_reverse/rfs.go
+++ b/internal/fusefrontend_reverse/rfs.go
@@ -221,6 +221,16 @@ func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr
// Calculate encrypted file size
if a.IsRegular() {
a.Size = rfs.contentEnc.PlainSizeToCipherSize(a.Size)
+ } else if a.IsSymlink() {
+ var linkTarget string
+ var readlinkStatus fuse.Status
+
+ linkTarget, readlinkStatus = rfs.Readlink(relPath, context)
+ if !readlinkStatus.Ok() {
+ return nil, readlinkStatus
+ }
+
+ a.Size = uint64(len(linkTarget))
}
return a, fuse.OK
}
diff --git a/tests/reverse/correctness_test.go b/tests/reverse/correctness_test.go
index db64983..bebf341 100644
--- a/tests/reverse/correctness_test.go
+++ b/tests/reverse/correctness_test.go
@@ -6,6 +6,7 @@ import (
"syscall"
"testing"
+ "github.com/rfjakob/gocryptfs/internal/ctlsock"
"github.com/rfjakob/gocryptfs/tests/test_helpers"
)
@@ -51,6 +52,43 @@ func TestSymlinks(t *testing.T) {
}
}
+// Symbolic link dentry sizes should be set to the length of the string
+// that contains the target path.
+func TestSymlinkDentrySize(t *testing.T) {
+ symlink := "a_symlink"
+
+ mnt, err := ioutil.TempDir(test_helpers.TmpDir, "reverse_mnt_")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ sock := mnt + ".sock"
+ test_helpers.MountOrFatal(t, "ctlsock_reverse_test_fs", mnt, "-reverse", "-extpass", "echo test", "-ctlsock="+sock)
+ defer test_helpers.UnmountPanic(mnt)
+
+ req := ctlsock.RequestStruct{EncryptPath: symlink}
+ symlinkResponse := test_helpers.QueryCtlSock(t, sock, req)
+ if symlinkResponse.ErrNo != 0 {
+ t.Errorf("Encrypt: %q ErrNo=%d ErrText=%s", symlink, symlinkResponse.ErrNo, symlinkResponse.ErrText)
+ }
+
+ fi, err := os.Lstat(mnt + "/" + symlinkResponse.Result)
+ if err != nil {
+ t.Errorf("Lstat: %v", err)
+ }
+
+ target, err := os.Readlink(mnt + "/" + symlinkResponse.Result)
+ if err != nil {
+ t.Errorf("Readlink: %v", err)
+ }
+
+ if fi.Size() != int64(len(target)) {
+ t.Errorf("Lstat reports that symbolic link %q's dentry size is %d, but this does not "+
+ "match the length of the string returned by readlink, which is %d.",
+ symlink, fi.Size(), len(target))
+ }
+}
+
// .gocryptfs.reverse.conf in the plaintext dir should be visible as
// gocryptfs.conf
func TestConfigMapping(t *testing.T) {
diff --git a/tests/reverse/ctlsock_reverse_test_fs/a_symlink b/tests/reverse/ctlsock_reverse_test_fs/a_symlink
new file mode 120000
index 0000000..06ed148
--- /dev/null
+++ b/tests/reverse/ctlsock_reverse_test_fs/a_symlink
@@ -0,0 +1 @@
+dir/dir/file \ No newline at end of file