aboutsummaryrefslogtreecommitdiff
path: root/internal/syscallcompat/sys_linux.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-06-02 19:10:36 +0200
committerJakob Unterwurzacher2021-06-02 19:10:36 +0200
commita38e5988bae3319a2c1c6745064f5785a0971d05 (patch)
tree6ae7645bba6d4f1b265b6dc859db6c7bbce7165f /internal/syscallcompat/sys_linux.go
parentb23e21f61fc51ffa9c1c823778553925e1cc115e (diff)
fusefrontend: run acl Setxattr in user context
The result of setting an acl depends on who runs the operation! Fixes fuse-xfstests generic/375 (see https://github.com/rfjakob/fuse-xfstests/wiki/results_2021-05-19)
Diffstat (limited to 'internal/syscallcompat/sys_linux.go')
-rw-r--r--internal/syscallcompat/sys_linux.go20
1 files changed, 20 insertions, 0 deletions
diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go
index 36ce7d5..45c18d2 100644
--- a/internal/syscallcompat/sys_linux.go
+++ b/internal/syscallcompat/sys_linux.go
@@ -130,6 +130,9 @@ func asUser(f func() (int, error), context *fuse.Context) (int, error) {
//
// It switches the current thread to the new user, performs the syscall,
// and switches back.
+//
+// If `context` is nil, this function behaves like ordinary Openat (no
+// user switching).
func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) {
f := func() (int, error) {
return Openat(dirfd, path, flags, mode)
@@ -143,6 +146,7 @@ func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
}
// MknodatUser runs the Mknodat syscall in the context of a different user.
+// If `context` is nil, this function behaves like ordinary Mknodat.
//
// See OpenatUser() for how this works.
func MknodatUser(dirfd int, path string, mode uint32, dev int, context *fuse.Context) (err error) {
@@ -195,6 +199,7 @@ func FchmodatNofollow(dirfd int, path string, mode uint32) (err error) {
}
// SymlinkatUser runs the Symlinkat syscall in the context of a different user.
+// If `context` is nil, this function behaves like ordinary Symlinkat.
//
// See OpenatUser() for how this works.
func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) {
@@ -207,6 +212,7 @@ func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.C
}
// MkdiratUser runs the Mkdirat syscall in the context of a different user.
+// If `context` is nil, this function behaves like ordinary Mkdirat.
//
// See OpenatUser() for how this works.
func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (err error) {
@@ -218,6 +224,20 @@ func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (er
return err
}
+// LsetxattrUser runs the Lsetxattr syscall in the context of a different user.
+// This is useful when setting ACLs, as the result depends on the user running
+// the operation (see fuse-xfstests generic/375).
+//
+// If `context` is nil, this function behaves like ordinary Lsetxattr.
+func LsetxattrUser(path string, attr string, data []byte, flags int, context *fuse.Context) (err error) {
+ f := func() (int, error) {
+ err := unix.Lsetxattr(path, attr, data, flags)
+ return -1, err
+ }
+ _, err = asUser(f, context)
+ return err
+}
+
func timesToTimespec(a *time.Time, m *time.Time) []unix.Timespec {
ts := make([]unix.Timespec, 2)
ts[0] = unix.Timespec(fuse.UtimeToTimespec(a))