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.
This commit is contained in:
M. Vefa Bicakci 2017-03-07 12:09:09 +03:00 committed by Jakob Unterwurzacher
parent 6e9b6e17c3
commit d48ccb3dda
3 changed files with 49 additions and 0 deletions

View File

@ -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
}

View File

@ -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) {

View File

@ -0,0 +1 @@
dir/dir/file