From 22cd9cf174e8a93787b01f6dd7b09247f9642286 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Wed, 26 Feb 2025 21:12:56 +0100 Subject: syscallcompat: add asUser for darwin and make OpenatUser and friends shared --- internal/syscallcompat/asuser_darwin.go | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 internal/syscallcompat/asuser_darwin.go (limited to 'internal/syscallcompat/asuser_darwin.go') diff --git a/internal/syscallcompat/asuser_darwin.go b/internal/syscallcompat/asuser_darwin.go new file mode 100644 index 0000000..5da2782 --- /dev/null +++ b/internal/syscallcompat/asuser_darwin.go @@ -0,0 +1,46 @@ +package syscallcompat + +import ( + "runtime" + "syscall" + + "github.com/hanwen/go-fuse/v2/fuse" +) + +// asUser runs `f()` under the effective uid, gid, groups specified +// in `context`. +// +// If `context` is nil, `f()` is executed directly without switching user id. +func asUser(f func() (int, error), context *fuse.Context) (int, error) { + if context == nil { + return f() + } + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err := pthread_setugid_np(context.Owner.Uid, context.Owner.Gid) + if err != nil { + return -1, err + } + + const ( + // KAUTH_UID_NONE and KAUTH_GID_NONE are special values to + // revert permissions to the process credentials. + KAUTH_UID_NONE = ^uint32(0) - 100 + KAUTH_GID_NONE = ^uint32(0) - 100 + ) + + defer pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) + + return f() +} + +// Unfortunately pthread_setugid_np does not have a syscall wrapper yet. +func pthread_setugid_np(uid uint32, gid uint32) (err error) { + _, _, e1 := syscall.RawSyscall(syscall.SYS_SETTID, uintptr(uid), uintptr(gid), 0) + if e1 != 0 { + err = e1 + } + return +} -- cgit v1.2.3