diff options
| author | Jakob Unterwurzacher | 2018-11-04 22:01:18 +0100 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2019-01-01 16:24:25 +0100 | 
| commit | 4fae240153a5300b7108bf5c2de2b6581c8ee7fd (patch) | |
| tree | 383ae37643dbec97ae786358ad22488f7eb351d0 /internal/fusefrontend | |
| parent | 21f1f858b9bebb20fdb9bb3f99189279bb6c6976 (diff) | |
fusefrontend: make Readlink() symlink-safe
Now symlink-safe through Readlinkat().
Diffstat (limited to 'internal/fusefrontend')
| -rw-r--r-- | internal/fusefrontend/fs.go | 14 | 
1 files changed, 9 insertions, 5 deletions
| diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index a301231..022fd5c 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -377,6 +377,8 @@ func (fs *FS) StatFs(path string) *fuse.StatfsOut {  // decryptSymlinkTarget: "cData64" is base64-decoded and decrypted  // like file contents (GCM).  // The empty string decrypts to the empty string. +// +// This function does not do any I/O and is hence symlink-safe.  func (fs *FS) decryptSymlinkTarget(cData64 string) (string, error) {  	if cData64 == "" {  		return "", nil @@ -392,14 +394,16 @@ func (fs *FS) decryptSymlinkTarget(cData64 string) (string, error) {  	return string(data), nil  } -// Readlink implements pathfs.Filesystem. +// Readlink - FUSE call. +// +// Symlink-safe through openBackingDir() + Readlinkat().  func (fs *FS) Readlink(relPath string, context *fuse.Context) (out string, status fuse.Status) { -	cPath, err := fs.encryptPath(relPath) +	dirfd, cName, err := fs.openBackingDir(relPath)  	if err != nil {  		return "", fuse.ToStatus(err)  	} -	cAbsPath := filepath.Join(fs.args.Cipherdir, cPath) -	cTarget, err := os.Readlink(cAbsPath) +	defer syscall.Close(dirfd) +	cTarget, err := syscallcompat.Readlinkat(dirfd, cName)  	if err != nil {  		return "", fuse.ToStatus(err)  	} @@ -409,7 +413,7 @@ func (fs *FS) Readlink(relPath string, context *fuse.Context) (out string, statu  	// Symlinks are encrypted like file contents (GCM) and base64-encoded  	target, err := fs.decryptSymlinkTarget(cTarget)  	if err != nil { -		tlog.Warn.Printf("Readlink %q: decrypting target failed: %v", cPath, err) +		tlog.Warn.Printf("Readlink %q: decrypting target failed: %v", cName, err)  		return "", fuse.EIO  	}  	return string(target), fuse.OK | 
