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:
parent
6e9b6e17c3
commit
d48ccb3dda
@ -221,6 +221,16 @@ func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr
|
|||||||
// Calculate encrypted file size
|
// Calculate encrypted file size
|
||||||
if a.IsRegular() {
|
if a.IsRegular() {
|
||||||
a.Size = rfs.contentEnc.PlainSizeToCipherSize(a.Size)
|
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
|
return a, fuse.OK
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/ctlsock"
|
||||||
"github.com/rfjakob/gocryptfs/tests/test_helpers"
|
"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.reverse.conf in the plaintext dir should be visible as
|
||||||
// gocryptfs.conf
|
// gocryptfs.conf
|
||||||
func TestConfigMapping(t *testing.T) {
|
func TestConfigMapping(t *testing.T) {
|
||||||
|
1
tests/reverse/ctlsock_reverse_test_fs/a_symlink
Symbolic link
1
tests/reverse/ctlsock_reverse_test_fs/a_symlink
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
dir/dir/file
|
Loading…
Reference in New Issue
Block a user