fusefrontend: -allow_other: Use SymlinkatUser in Symlink FUSE call.
Instead of manually adjusting the user after creating the symlink, adjust effective permissions and let the kernel deal with it. Related to https://github.com/rfjakob/gocryptfs/issues/338.
This commit is contained in:
parent
1fbe7798cf
commit
efc280330c
@ -483,6 +483,10 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
|
|||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
defer syscall.Close(dirfd)
|
defer syscall.Close(dirfd)
|
||||||
|
// Make sure context is nil if we don't want to preserve the owner
|
||||||
|
if !fs.args.PreserveOwner {
|
||||||
|
context = nil
|
||||||
|
}
|
||||||
cTarget := target
|
cTarget := target
|
||||||
if !fs.args.PlaintextNames {
|
if !fs.args.PlaintextNames {
|
||||||
// Symlinks are encrypted like file contents (GCM) and base64-encoded
|
// Symlinks are encrypted like file contents (GCM) and base64-encoded
|
||||||
@ -495,26 +499,15 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
|
|||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Create "gocryptfs.longfile." symlink
|
// Create "gocryptfs.longfile." symlink
|
||||||
err = syscallcompat.Symlinkat(cTarget, dirfd, cName)
|
err = syscallcompat.SymlinkatUser(cTarget, dirfd, cName, context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
nametransform.DeleteLongNameAt(dirfd, cName)
|
nametransform.DeleteLongNameAt(dirfd, cName)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create symlink
|
// Create symlink
|
||||||
err = syscallcompat.Symlinkat(cTarget, dirfd, cName)
|
err = syscallcompat.SymlinkatUser(cTarget, dirfd, cName, context)
|
||||||
}
|
}
|
||||||
if err != nil {
|
return fuse.ToStatus(err)
|
||||||
return fuse.ToStatus(err)
|
|
||||||
}
|
|
||||||
// Set owner
|
|
||||||
if fs.args.PreserveOwner {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fuse.OK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename - FUSE call.
|
// Rename - FUSE call.
|
||||||
|
@ -80,6 +80,11 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
|
|||||||
return emulateSymlinkat(oldpath, newdirfd, newpath)
|
return emulateSymlinkat(oldpath, newdirfd, newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) {
|
||||||
|
// FIXME: take into account context.Owner
|
||||||
|
return Symlinkat(oldpath, newdirfd, newpath)
|
||||||
|
}
|
||||||
|
|
||||||
func Mkdirat(dirfd int, path string, mode uint32) (err error) {
|
func Mkdirat(dirfd int, path string, mode uint32) (err error) {
|
||||||
return emulateMkdirat(dirfd, path, mode)
|
return emulateMkdirat(dirfd, path, mode)
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,28 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
|
|||||||
return unix.Symlinkat(oldpath, newdirfd, newpath)
|
return unix.Symlinkat(oldpath, newdirfd, newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SymlinkatUser runs the Symlinkat syscall in the context of a different user.
|
||||||
|
func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) {
|
||||||
|
if context != nil {
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
err = syscall.Setregid(-1, int(context.Owner.Gid))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer syscall.Setregid(-1, 0)
|
||||||
|
|
||||||
|
err = syscall.Setreuid(-1, int(context.Owner.Uid))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer syscall.Setreuid(-1, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Symlinkat(oldpath, newdirfd, newpath)
|
||||||
|
}
|
||||||
|
|
||||||
// Mkdirat syscall.
|
// Mkdirat syscall.
|
||||||
func Mkdirat(dirfd int, path string, mode uint32) (err error) {
|
func Mkdirat(dirfd int, path string, mode uint32) (err error) {
|
||||||
return syscall.Mkdirat(dirfd, path, mode)
|
return syscall.Mkdirat(dirfd, path, mode)
|
||||||
|
Loading…
Reference in New Issue
Block a user