diff options
| author | Jakob Unterwurzacher | 2018-09-22 20:10:34 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2018-09-23 12:17:26 +0200 | 
| commit | c270b21efc1d9ecbe5c913c733204f826e263747 (patch) | |
| tree | f001342e38ab81eeea1292c7a405d30321624b6d | |
| parent | 22fba4ac3ed09ba07d1defb60436fb7a17095d09 (diff) | |
fusefrontend: get rid of os.File* wrapping
Directly use int file descriptors for the dirfd
and get rid of one level of indirection.
| -rw-r--r-- | init_dir.go | 2 | ||||
| -rw-r--r-- | internal/fusefrontend/fs.go | 82 | ||||
| -rw-r--r-- | internal/fusefrontend/fs_dir.go | 49 | ||||
| -rw-r--r-- | internal/fusefrontend/names.go | 9 | ||||
| -rw-r--r-- | internal/nametransform/diriv.go | 14 | ||||
| -rw-r--r-- | internal/nametransform/longnames.go | 8 | ||||
| -rw-r--r-- | tests/test_helpers/helpers.go | 2 | 
7 files changed, 82 insertions, 84 deletions
| diff --git a/init_dir.go b/init_dir.go index e264cf0..6bc977f 100644 --- a/init_dir.go +++ b/init_dir.go @@ -96,7 +96,7 @@ func initDir(args *argContainer) {  	// Forward mode with filename encryption enabled needs a gocryptfs.diriv file  	// in the root dir  	if !args.plaintextnames && !args.reverse { -		err = nametransform.WriteDirIV(nil, args.cipherdir) +		err = nametransform.WriteDirIV(-1, args.cipherdir)  		if err != nil {  			tlog.Fatal.Println(err)  			os.Exit(exitcodes.Init) diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 0e198d6..71d550e 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -129,7 +129,7 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n  	if err != nil {  		return nil, fuse.ToStatus(err)  	} -	fd, err := syscallcompat.Openat(int(dirfd.Fd()), cName, newFlags, 0) +	fd, err := syscallcompat.Openat(dirfd, cName, newFlags, 0)  	// Handle a few specific errors  	if err != nil {  		if err == syscall.EMFILE { @@ -150,8 +150,8 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n  // problem if the file permissions do not allow reading (i.e. 0200 permissions).  // This function works around that problem by chmod'ing the file, obtaining a fd,  // and chmod'ing it back. -func (fs *FS) openWriteOnlyFile(dirfd *os.File, cName string, newFlags int) (fuseFile nodefs.File, status fuse.Status) { -	woFd, err := syscallcompat.Openat(int(dirfd.Fd()), cName, syscall.O_WRONLY|syscall.O_NOFOLLOW, 0) +func (fs *FS) openWriteOnlyFile(dirfd int, cName string, newFlags int) (fuseFile nodefs.File, status fuse.Status) { +	woFd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NOFOLLOW, 0)  	if err != nil {  		return nil, fuse.ToStatus(err)  	} @@ -186,7 +186,7 @@ func (fs *FS) openWriteOnlyFile(dirfd *os.File, cName string, newFlags int) (fus  			tlog.Warn.Printf("openWriteOnlyFile: reverting permissions failed: %v", err2)  		}  	}() -	rwFd, err := syscallcompat.Openat(int(dirfd.Fd()), cName, newFlags, 0) +	rwFd, err := syscallcompat.Openat(dirfd, cName, newFlags, 0)  	if err != nil {  		return nil, fuse.ToStatus(err)  	} @@ -210,12 +210,12 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte  	// Handle long file name  	if !fs.args.PlaintextNames && nametransform.IsLongContent(cName) { -		var dirfd *os.File -		dirfd, err = os.Open(filepath.Dir(cPath)) +		var dirfd int +		dirfd, err = syscall.Open(filepath.Dir(cPath), syscall.O_RDONLY|syscall.O_DIRECTORY, 0)  		if err != nil {  			return nil, fuse.ToStatus(err)  		} -		defer dirfd.Close() +		defer syscall.Close(dirfd)  		// Create ".name"  		err = fs.nameTransform.WriteLongName(dirfd, cName, path) @@ -225,7 +225,7 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte  		// Create content  		var fdRaw int -		fdRaw, err = syscallcompat.Openat(int(dirfd.Fd()), cName, newFlags|os.O_CREATE|os.O_EXCL, mode) +		fdRaw, err = syscallcompat.Openat(dirfd, cName, newFlags|os.O_CREATE|os.O_EXCL, mode)  		if err != nil {  			nametransform.DeleteLongName(dirfd, cName)  			return nil, fuse.ToStatus(err) @@ -257,10 +257,10 @@ func (fs *FS) Chmod(path string, mode uint32, context *fuse.Context) (code fuse.  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() +	defer syscall.Close(dirfd)  	// os.Chmod goes through the "syscallMode" translation function that messes  	// up the suid and sgid bits. So use a syscall directly. -	err = syscallcompat.Fchmodat(int(dirfd.Fd()), cName, mode, unix.AT_SYMLINK_NOFOLLOW) +	err = syscallcompat.Fchmodat(dirfd, cName, mode, unix.AT_SYMLINK_NOFOLLOW)  	return fuse.ToStatus(err)  } @@ -273,8 +273,8 @@ func (fs *FS) Chown(path string, uid uint32, gid uint32, context *fuse.Context)  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() -	code = fuse.ToStatus(syscallcompat.Fchownat(int(dirfd.Fd()), cName, int(uid), int(gid), unix.AT_SYMLINK_NOFOLLOW)) +	defer syscall.Close(dirfd) +	code = fuse.ToStatus(syscallcompat.Fchownat(dirfd, cName, int(uid), int(gid), unix.AT_SYMLINK_NOFOLLOW))  	if !code.Ok() {  		return code  	} @@ -284,7 +284,7 @@ func (fs *FS) Chown(path string, uid uint32, gid uint32, context *fuse.Context)  		// Instead of checking if "cName" is a directory, we just blindly  		// execute the chown on "cName/gocryptfs.diriv" and ignore errors.  		dirIVPath := filepath.Join(cName, nametransform.DirIVFilename) -		syscallcompat.Fchownat(int(dirfd.Fd()), dirIVPath, int(uid), int(gid), unix.AT_SYMLINK_NOFOLLOW) +		syscallcompat.Fchownat(dirfd, dirIVPath, int(uid), int(gid), unix.AT_SYMLINK_NOFOLLOW)  	}  	return fuse.OK  } @@ -298,7 +298,7 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context)  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() +	defer syscall.Close(dirfd)  	// Create ".name" file to store long file name (except in PlaintextNames mode)  	if !fs.args.PlaintextNames && nametransform.IsLongContent(cName) {  		err = fs.nameTransform.WriteLongName(dirfd, cName, path) @@ -306,20 +306,20 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context)  			return fuse.ToStatus(err)  		}  		// Create "gocryptfs.longfile." device node -		err = syscallcompat.Mknodat(int(dirfd.Fd()), cName, mode, int(dev)) +		err = syscallcompat.Mknodat(dirfd, cName, mode, int(dev))  		if err != nil {  			nametransform.DeleteLongName(dirfd, cName)  		}  	} else {  		// Create regular device node -		err = syscallcompat.Mknodat(int(dirfd.Fd()), cName, mode, int(dev)) +		err = syscallcompat.Mknodat(dirfd, cName, mode, int(dev))  	}  	if err != nil {  		return fuse.ToStatus(err)  	}  	// Set owner  	if fs.args.PreserveOwner { -		err = syscallcompat.Fchownat(int(dirfd.Fd()), cName, int(context.Owner.Uid), +		err = syscallcompat.Fchownat(dirfd, cName, int(context.Owner.Uid),  			int(context.Owner.Gid), unix.AT_SYMLINK_NOFOLLOW)  		if err != nil {  			tlog.Warn.Printf("Mknod: Fchownat failed: %v", err) @@ -416,9 +416,9 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() +	defer syscall.Close(dirfd)  	// Delete content -	err = syscallcompat.Unlinkat(int(dirfd.Fd()), cName, 0) +	err = syscallcompat.Unlinkat(dirfd, cName, 0)  	if err != nil {  		return fuse.ToStatus(err)  	} @@ -454,7 +454,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() +	defer syscall.Close(dirfd)  	cTarget := target  	if !fs.args.PlaintextNames {  		// Symlinks are encrypted like file contents (GCM) and base64-encoded @@ -467,20 +467,20 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co  			return fuse.ToStatus(err)  		}  		// Create "gocryptfs.longfile." symlink -		err = syscallcompat.Symlinkat(cTarget, int(dirfd.Fd()), cName) +		err = syscallcompat.Symlinkat(cTarget, dirfd, cName)  		if err != nil {  			nametransform.DeleteLongName(dirfd, cName)  		}  	} else {  		// Create symlink -		err = syscallcompat.Symlinkat(cTarget, int(dirfd.Fd()), cName) +		err = syscallcompat.Symlinkat(cTarget, dirfd, cName)  	}  	if err != nil {  		return fuse.ToStatus(err)  	}  	// Set owner  	if fs.args.PreserveOwner { -		err = syscallcompat.Fchownat(int(dirfd.Fd()), cName, int(context.Owner.Uid), +		err = syscallcompat.Fchownat(dirfd, cName, int(context.Owner.Uid),  			int(context.Owner.Gid), unix.AT_SYMLINK_NOFOLLOW)  		if err != nil {  			tlog.Warn.Printf("Symlink: Fchownat failed: %v", err) @@ -510,32 +510,32 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod  		return fuse.ToStatus(syscall.Rename(cOldPath, cNewPath))  	}  	// Handle long source file name -	var oldDirFd *os.File -	var finalOldDirFd int +	oldDirFd := -1 +	finalOldDirFd := -1  	var finalOldPath = cOldPath  	cOldName := filepath.Base(cOldPath)  	if nametransform.IsLongContent(cOldName) { -		oldDirFd, err = os.Open(filepath.Dir(cOldPath)) +		oldDirFd, err = syscall.Open(filepath.Dir(cOldPath), syscall.O_RDONLY|syscall.O_DIRECTORY, 0)  		if err != nil {  			return fuse.ToStatus(err)  		} -		defer oldDirFd.Close() -		finalOldDirFd = int(oldDirFd.Fd()) +		defer syscall.Close(oldDirFd) +		finalOldDirFd = oldDirFd  		// Use relative path  		finalOldPath = cOldName  	}  	// Handle long destination file name -	var newDirFd *os.File -	var finalNewDirFd int -	var finalNewPath = cNewPath +	newDirFd := -1 +	finalNewDirFd := -1 +	finalNewPath := cNewPath  	cNewName := filepath.Base(cNewPath)  	if nametransform.IsLongContent(cNewName) { -		newDirFd, err = os.Open(filepath.Dir(cNewPath)) +		newDirFd, err = syscall.Open(filepath.Dir(cNewPath), syscall.O_RDONLY|syscall.O_DIRECTORY, 0)  		if err != nil {  			return fuse.ToStatus(err)  		} -		defer newDirFd.Close() -		finalNewDirFd = int(newDirFd.Fd()) +		defer syscall.Close(newDirFd) +		finalNewDirFd = newDirFd  		// Use relative path  		finalNewPath = cNewName  		// Create destination .name file @@ -545,7 +545,7 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod  		// file anyway. We still set newDirFd to nil to ensure that we do not delete  		// the file on error.  		if err == syscall.EEXIST { -			newDirFd = nil +			newDirFd = -1  		} else if err != nil {  			return fuse.ToStatus(err)  		} @@ -565,13 +565,13 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod  		}  	}  	if err != nil { -		if newDirFd != nil { +		if newDirFd >= 0 {  			// Roll back .name creation  			nametransform.DeleteLongName(newDirFd, cNewName)  		}  		return fuse.ToStatus(err)  	} -	if oldDirFd != nil { +	if oldDirFd >= 0 {  		nametransform.DeleteLongName(oldDirFd, cOldName)  	}  	return fuse.OK @@ -586,12 +586,12 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer oldDirFd.Close() +	defer syscall.Close(oldDirFd)  	newDirFd, cNewName, err := fs.openBackingDir(newPath)  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer newDirFd.Close() +	defer syscall.Close(newDirFd)  	// Handle long file name (except in PlaintextNames mode)  	if !fs.args.PlaintextNames && nametransform.IsLongContent(cNewName) {  		err = fs.nameTransform.WriteLongName(newDirFd, cNewName, newPath) @@ -599,13 +599,13 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code  			return fuse.ToStatus(err)  		}  		// Create "gocryptfs.longfile." link -		err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0) +		err = syscallcompat.Linkat(oldDirFd, cOldName, newDirFd, cNewName, 0)  		if err != nil {  			nametransform.DeleteLongName(newDirFd, cNewName)  		}  	} else {  		// Create regular link -		err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0) +		err = syscallcompat.Linkat(oldDirFd, cOldName, newDirFd, cNewName, 0)  	}  	return fuse.ToStatus(err)  } diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go index b9266dd..df22100 100644 --- a/internal/fusefrontend/fs_dir.go +++ b/internal/fusefrontend/fs_dir.go @@ -26,7 +26,7 @@ const dsStoreName = ".DS_Store"  // mkdirWithIv - create a new directory and corresponding diriv file. dirfd  // should be a handle to the parent directory, cName is the name of the new  // directory and mode specifies the access permissions to use. -func (fs *FS) mkdirWithIv(dirfd *os.File, cName string, mode uint32) error { +func (fs *FS) mkdirWithIv(dirfd int, cName string, mode uint32) error {  	// Between the creation of the directory and the creation of gocryptfs.diriv  	// the directory is inconsistent. Take the lock to prevent other readers  	// from seeing it. @@ -34,14 +34,14 @@ func (fs *FS) mkdirWithIv(dirfd *os.File, cName string, mode uint32) error {  	// The new directory may take the place of an older one that is still in the cache  	fs.nameTransform.DirIVCache.Clear()  	defer fs.dirIVLock.Unlock() -	err := syscallcompat.Mkdirat(int(dirfd.Fd()), cName, mode) +	err := syscallcompat.Mkdirat(dirfd, cName, mode)  	if err != nil {  		return err  	}  	// Create gocryptfs.diriv  	err = nametransform.WriteDirIV(dirfd, cName)  	if err != nil { -		err2 := syscallcompat.Unlinkat(int(dirfd.Fd()), cName, unix.AT_REMOVEDIR) +		err2 := syscallcompat.Unlinkat(dirfd, cName, unix.AT_REMOVEDIR)  		if err2 != nil {  			tlog.Warn.Printf("mkdirWithIv: rollback failed: %v", err2)  		} @@ -58,12 +58,12 @@ func (fs *FS) Mkdir(newPath string, mode uint32, context *fuse.Context) (code fu  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer dirfd.Close() +	defer syscall.Close(dirfd)  	if fs.args.PlaintextNames { -		err = syscallcompat.Mkdirat(int(dirfd.Fd()), cName, mode) +		err = syscallcompat.Mkdirat(dirfd, cName, mode)  		// Set owner  		if fs.args.PreserveOwner { -			err = syscallcompat.Fchownat(int(dirfd.Fd()), cName, int(context.Owner.Uid), +			err = syscallcompat.Fchownat(dirfd, cName, int(context.Owner.Uid),  				int(context.Owner.Gid), unix.AT_SYMLINK_NOFOLLOW)  			if err != nil {  				tlog.Warn.Printf("Mkdir: Fchownat failed: %v", err) @@ -98,19 +98,19 @@ func (fs *FS) Mkdir(newPath string, mode uint32, context *fuse.Context) (code fu  	}  	// Set permissions back to what the user wanted  	if origMode != mode { -		err = syscallcompat.Fchmodat(int(dirfd.Fd()), cName, origMode, unix.AT_SYMLINK_NOFOLLOW) +		err = syscallcompat.Fchmodat(dirfd, cName, origMode, unix.AT_SYMLINK_NOFOLLOW)  		if err != nil {  			tlog.Warn.Printf("Mkdir: Fchmodat failed: %v", err)  		}  	}  	// Set owner  	if fs.args.PreserveOwner { -		err = syscallcompat.Fchownat(int(dirfd.Fd()), cName, int(context.Owner.Uid), +		err = syscallcompat.Fchownat(dirfd, cName, int(context.Owner.Uid),  			int(context.Owner.Gid), unix.AT_SYMLINK_NOFOLLOW)  		if err != nil {  			tlog.Warn.Printf("Mkdir: Fchownat 1 failed: %v", err)  		} -		err = syscallcompat.Fchownat(int(dirfd.Fd()), filepath.Join(cName, nametransform.DirIVFilename), +		err = syscallcompat.Fchownat(dirfd, filepath.Join(cName, nametransform.DirIVFilename),  			int(context.Owner.Uid), int(context.Owner.Gid), unix.AT_SYMLINK_NOFOLLOW)  		if err != nil {  			tlog.Warn.Printf("Mkdir: Fchownat 2 failed: %v", err) @@ -120,9 +120,9 @@ func (fs *FS) Mkdir(newPath string, mode uint32, context *fuse.Context) (code fu  }  // haveDsstore return true if one of the entries in "names" is ".DS_Store". -func haveDsstore(names []string) bool { -	for _, n := range names { -		if n == dsStoreName { +func haveDsstore(entries []fuse.DirEntry) bool { +	for _, e := range entries { +		if e.Name == dsStoreName {  			return true  		}  	} @@ -140,14 +140,14 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {  		return fuse.ToStatus(err)  	}  	parentDir := filepath.Dir(cPath) -	parentDirFd, err := os.Open(parentDir) +	parentDirFd, err := syscall.Open(parentDir, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)  	if err != nil {  		return fuse.ToStatus(err)  	} -	defer parentDirFd.Close() +	defer syscall.Close(parentDirFd)  	cName := filepath.Base(cPath) -	dirfdRaw, err := syscallcompat.Openat(int(parentDirFd.Fd()), cName, +	dirfd, err := syscallcompat.Openat(parentDirFd, cName,  		syscall.O_RDONLY|syscall.O_NOFOLLOW, 0)  	if err == syscall.EACCES {  		// We need permission to read and modify the directory @@ -169,7 +169,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {  		// Retry open  		var st syscall.Stat_t  		syscall.Lstat(cPath, &st) -		dirfdRaw, err = syscallcompat.Openat(int(parentDirFd.Fd()), cName, +		dirfd, err = syscallcompat.Openat(parentDirFd, cName,  			syscall.O_RDONLY|syscall.O_NOFOLLOW, 0)  		// Undo the chmod if removing the directory failed  		defer func() { @@ -185,11 +185,10 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {  		tlog.Debug.Printf("Rmdir: Open: %v", err)  		return fuse.ToStatus(err)  	} -	dirfd := os.NewFile(uintptr(dirfdRaw), cName) -	defer dirfd.Close() +	defer syscall.Close(dirfd)  retry:  	// Check directory contents -	children, err := dirfd.Readdirnames(10) +	children, err := syscallcompat.Getdents(dirfd)  	if err == io.EOF {  		// The directory is empty  		tlog.Warn.Printf("Rmdir: %q: gocryptfs.diriv is missing", cPath) @@ -223,27 +222,27 @@ retry:  	// Protect against concurrent readers.  	fs.dirIVLock.Lock()  	defer fs.dirIVLock.Unlock() -	err = syscallcompat.Renameat(int(dirfd.Fd()), nametransform.DirIVFilename, -		int(parentDirFd.Fd()), tmpName) +	err = syscallcompat.Renameat(dirfd, nametransform.DirIVFilename, +		parentDirFd, tmpName)  	if err != nil {  		tlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v",  			nametransform.DirIVFilename, tmpName, err)  		return fuse.ToStatus(err)  	}  	// Actual Rmdir -	err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), cName, unix.AT_REMOVEDIR) +	err = syscallcompat.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR)  	if err != nil {  		// This can happen if another file in the directory was created in the  		// meantime, undo the rename -		err2 := syscallcompat.Renameat(int(parentDirFd.Fd()), tmpName, -			int(dirfd.Fd()), nametransform.DirIVFilename) +		err2 := syscallcompat.Renameat(parentDirFd, tmpName, +			dirfd, nametransform.DirIVFilename)  		if err != nil {  			tlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)  		}  		return fuse.ToStatus(err)  	}  	// Delete "gocryptfs.diriv.rmdir.XYZ" -	err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName, 0) +	err = syscallcompat.Unlinkat(parentDirFd, tmpName, 0)  	if err != nil {  		tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)  	} diff --git a/internal/fusefrontend/names.go b/internal/fusefrontend/names.go index d7fbdce..86c87f0 100644 --- a/internal/fusefrontend/names.go +++ b/internal/fusefrontend/names.go @@ -3,7 +3,6 @@ package fusefrontend  // This file forwards file encryption operations to cryptfs  import ( -	"os"  	"path/filepath"  	"github.com/rfjakob/gocryptfs/internal/configfile" @@ -45,17 +44,17 @@ func (fs *FS) getBackingPath(relPath string) (string, error) {  // "relPath" and returns the dirfd and the encrypted basename.  // The caller should then use Openat(dirfd, cName, ...) and friends.  // openBackingDir is secure against symlink races. -func (fs *FS) openBackingDir(relPath string) (*os.File, string, error) { +func (fs *FS) openBackingDir(relPath string) (int, string, error) {  	cRelPath, err := fs.encryptPath(relPath)  	if err != nil { -		return nil, "", err +		return -1, "", err  	}  	// Open parent dir  	dirfd, err := syscallcompat.OpenDirNofollow(fs.args.Cipherdir, filepath.Dir(cRelPath))  	if err != nil { -		return nil, "", err +		return -1, "", err  	} -	return os.NewFile(uintptr(dirfd), cRelPath), filepath.Base(cRelPath), nil +	return dirfd, filepath.Base(cRelPath), nil  }  // encryptPath - encrypt relative plaintext path diff --git a/internal/nametransform/diriv.go b/internal/nametransform/diriv.go index 1a72d2a..81e44da 100644 --- a/internal/nametransform/diriv.go +++ b/internal/nametransform/diriv.go @@ -44,8 +44,8 @@ func ReadDirIV(dir string) (iv []byte, err error) {  // ReadDirIVAt reads "gocryptfs.diriv" from the directory that is opened as "dirfd".  // Using the dirfd makes it immune to concurrent renames of the directory. -func ReadDirIVAt(dirfd *os.File) (iv []byte, err error) { -	fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), DirIVFilename, +func ReadDirIVAt(dirfd int) (iv []byte, err error) { +	fdRaw, err := syscallcompat.Openat(dirfd, DirIVFilename,  		syscall.O_RDONLY|syscall.O_NOFOLLOW, 0)  	if err != nil {  		return nil, fmt.Errorf("openat failed: %v", err) @@ -82,16 +82,16 @@ func fdReadDirIV(fd *os.File) (iv []byte, err error) {  // "dir" should be a path (without slashes) relative to the directory  // described by "dirfd". This function is exported because it is used from  // pathfs_frontend, main, and also the automated tests. -func WriteDirIV(dirfd *os.File, dir string) error { +func WriteDirIV(dirfd int, dir string) error {  	// For relative paths we do not expect that "dir" contains slashes -	if dirfd != nil && strings.Contains(dir, "/") { +	if dirfd >= 0 && strings.Contains(dir, "/") {  		log.Panicf("WriteDirIV: Relative path should not contain slashes: %v", dir)  	}  	iv := cryptocore.RandBytes(DirIVLen)  	file := filepath.Join(dir, DirIVFilename)  	// 0400 permissions: gocryptfs.diriv should never be modified after creation.  	// Don't use "ioutil.WriteFile", it causes trouble on NFS: https://github.com/rfjakob/gocryptfs/issues/105 -	fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), file, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400) +	fdRaw, err := syscallcompat.Openat(dirfd, file, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400)  	if err != nil {  		tlog.Warn.Printf("WriteDirIV: Openat: %v", err)  		return err @@ -105,14 +105,14 @@ func WriteDirIV(dirfd *os.File, dir string) error {  			tlog.Warn.Printf("WriteDirIV: Write: %v", err)  		}  		// Delete incomplete gocryptfs.diriv file -		syscallcompat.Unlinkat(int(dirfd.Fd()), file, 0) +		syscallcompat.Unlinkat(dirfd, file, 0)  		return err  	}  	err = fd.Close()  	if err != nil {  		tlog.Warn.Printf("WriteDirIV: Close: %v", err)  		// Delete incomplete gocryptfs.diriv file -		syscallcompat.Unlinkat(int(dirfd.Fd()), file, 0) +		syscallcompat.Unlinkat(dirfd, file, 0)  		return err  	}  	return nil diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go index 614af47..01280a8 100644 --- a/internal/nametransform/longnames.go +++ b/internal/nametransform/longnames.go @@ -89,8 +89,8 @@ func ReadLongName(path string) (string, error) {  }  // DeleteLongName deletes "hashName.name". -func DeleteLongName(dirfd *os.File, hashName string) error { -	err := syscallcompat.Unlinkat(int(dirfd.Fd()), hashName+LongNameSuffix, 0) +func DeleteLongName(dirfd int, hashName string) error { +	err := syscallcompat.Unlinkat(dirfd, hashName+LongNameSuffix, 0)  	if err != nil {  		tlog.Warn.Printf("DeleteLongName: %v", err)  	} @@ -100,7 +100,7 @@ func DeleteLongName(dirfd *os.File, hashName string) error {  // WriteLongName encrypts plainName and writes it into "hashName.name".  // For the convenience of the caller, plainName may also be a path and will be  // converted internally. -func (n *NameTransform) WriteLongName(dirfd *os.File, hashName string, plainName string) (err error) { +func (n *NameTransform) WriteLongName(dirfd int, hashName string, plainName string) (err error) {  	plainName = filepath.Base(plainName)  	// Encrypt the basename @@ -111,7 +111,7 @@ func (n *NameTransform) WriteLongName(dirfd *os.File, hashName string, plainName  	cName := n.EncryptName(plainName, dirIV)  	// Write the encrypted name into hashName.name -	fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), hashName+LongNameSuffix, +	fdRaw, err := syscallcompat.Openat(dirfd, hashName+LongNameSuffix,  		syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL, 0600)  	if err != nil {  		// Don't warn if the file already exists - this is allowed for renames diff --git a/tests/test_helpers/helpers.go b/tests/test_helpers/helpers.go index 479bf72..b36056e 100644 --- a/tests/test_helpers/helpers.go +++ b/tests/test_helpers/helpers.go @@ -110,7 +110,7 @@ func ResetTmpDir(createDirIV bool) {  		panic(err)  	}  	if createDirIV { -		err = nametransform.WriteDirIV(nil, DefaultCipherDir) +		err = nametransform.WriteDirIV(-1, DefaultCipherDir)  		if err != nil {  			panic(err)  		} | 
