Skip to content

Commit 03b9d65

Browse files
committed
fusefrontend: -allow_other: Use OpenatUser in Create FUSE call.
Revert commit b22cc03. Instead of manually adjusting the user and mode after creating the file, adjust effective permissions and let the kernel deal with it. Related to #338.
1 parent 6693224 commit 03b9d65

File tree

3 files changed

+34
-28
lines changed

3 files changed

+34
-28
lines changed

internal/fusefrontend/fs.go

+6-28
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,11 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
238238
returnnil, fuse.ToStatus(err)
239239
}
240240
defersyscall.Close(dirfd)
241-
// Don't set full mode before we have set the correct owner. Files with SUID/SGID
242-
// mode belonging to the wrong owner would be a security risk. Even for other
243-
// modes, we don't want anyone else to open the file in the meantime: the fd would
244-
// stay open and could later be used to read the file.
245-
origMode:=mode
246-
iffs.args.PreserveOwner {
247-
mode=0000
248-
}
249241
fd:=-1
242+
// Make sure context is nil if we don't want to preserve the owner
243+
if!fs.args.PreserveOwner {
244+
context=nil
245+
}
250246
// Handle long file name
251247
if!fs.args.PlaintextNames&&nametransform.IsLongContent(cName) {
252248
// Create ".name"
@@ -255,14 +251,14 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
255251
returnnil, fuse.ToStatus(err)
256252
}
257253
// Create content
258-
fd, err=syscallcompat.Openat(dirfd, cName, newFlags|os.O_CREATE|os.O_EXCL, mode)
254+
fd, err=syscallcompat.OpenatUser(dirfd, cName, newFlags|os.O_CREATE|os.O_EXCL, mode, context)
259255
iferr!=nil {
260256
nametransform.DeleteLongNameAt(dirfd, cName)
261257
returnnil, fuse.ToStatus(err)
262258
}
263259
} else {
264260
// Create content, normal (short) file name
265-
fd, err=syscallcompat.Openat(dirfd, cName, newFlags|syscall.O_CREAT|syscall.O_EXCL, mode)
261+
fd, err=syscallcompat.OpenatUser(dirfd, cName, newFlags|syscall.O_CREAT|syscall.O_EXCL, mode, context)
266262
iferr!=nil {
267263
// xfstests generic/488 triggers this
268264
iferr==syscall.EMFILE {
@@ -273,24 +269,6 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
273269
returnnil, fuse.ToStatus(err)
274270
}
275271
}
276-
// Set owner
277-
iffs.args.PreserveOwner {
278-
err=syscall.Fchown(fd, int(context.Owner.Uid), int(context.Owner.Gid))
279-
iferr!=nil {
280-
tlog.Warn.Printf("Create %q: Fchown %d:%d failed: %v", cName, context.Owner.Uid, context.Owner.Gid, err)
281-
// In case of a failure, we don't want to proceed setting more
282-
// permissive modes.
283-
syscall.Close(fd)
284-
returnnil, fuse.ToStatus(err)
285-
}
286-
}
287-
// Set mode
288-
ifmode!=origMode {
289-
err=syscall.Fchmod(fd, origMode)
290-
iferr!=nil {
291-
tlog.Warn.Printf("Create %q: Fchmod %#o -> %#o failed: %v", cName, mode, origMode, err)
292-
}
293-
}
294272
f:=os.NewFile(uintptr(fd), cName)
295273
returnNewFile(f, fs)
296274
}

internal/syscallcompat/sys_darwin.go

+5
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
4646
returnemulateOpenat(dirfd, path, flags, mode)
4747
}
4848

49+
funcOpenatUser(dirfdint, pathstring, flagsint, modeuint32, context*fuse.Context) (fdint, errerror) {
50+
// FIXME: take into account context.Owner
51+
returnOpenat(dirfd, path, flags, mode)
52+
}
53+
4954
funcRenameat(olddirfdint, oldpathstring, newdirfdint, newpathstring) (errerror) {
5055
returnemulateRenameat(olddirfd, oldpath, newdirfd, newpath)
5156
}

internal/syscallcompat/sys_linux.go

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package syscallcompat
33

44
import (
55
"fmt"
6+
"runtime"
67
"sync"
78
"syscall"
89

@@ -75,6 +76,28 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
7576
returnsyscall.Openat(dirfd, path, flags, mode)
7677
}
7778

79+
// OpenatUser runs the Openat syscall in the context of a different user.
80+
funcOpenatUser(dirfdint, pathstring, flagsint, modeuint32, context*fuse.Context) (fdint, errerror) {
81+
ifcontext!=nil {
82+
runtime.LockOSThread()
83+
deferruntime.UnlockOSThread()
84+
85+
err=syscall.Setregid(-1, int(context.Owner.Gid))
86+
iferr!=nil {
87+
return-1, err
88+
}
89+
defersyscall.Setregid(-1, 0)
90+
91+
err=syscall.Setreuid(-1, int(context.Owner.Uid))
92+
iferr!=nil {
93+
return-1, err
94+
}
95+
defersyscall.Setreuid(-1, 0)
96+
}
97+
98+
returnOpenat(dirfd, path, flags, mode)
99+
}
100+
78101
// Renameat wraps the Renameat syscall.
79102
funcRenameat(olddirfdint, oldpathstring, newdirfdint, newpathstring) (errerror) {
80103
returnsyscall.Renameat(olddirfd, oldpath, newdirfd, newpath)

0 commit comments

Comments
 (0)
close