syscallcompat: fetch supplementary groups for OpenatUser & friends

Handled the same way in GlusterFS, disorderfs, libfuse.
Fixes https://github.com/rfjakob/gocryptfs/issues/394
This commit is contained in:
Sebastian Lackner 2019-05-01 13:18:44 +02:00 committed by Jakob Unterwurzacher
parent 96935e16b9
commit a97d14c42d
1 changed files with 53 additions and 0 deletions

View File

@ -3,7 +3,10 @@ package syscallcompat
import ( import (
"fmt" "fmt"
"io/ioutil"
"runtime" "runtime"
"strconv"
"strings"
"sync" "sync"
"syscall" "syscall"
"time" "time"
@ -59,12 +62,44 @@ func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
return syscall.Fallocate(fd, mode, off, len) return syscall.Fallocate(fd, mode, off, len)
} }
func getSupplementaryGroups(pid uint32) (gids []int) {
procPath := fmt.Sprintf("/proc/%d/task/%d/status", pid, pid)
blob, err := ioutil.ReadFile(procPath)
if err != nil {
return nil
}
lines := strings.Split(string(blob), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "Groups:") {
f := strings.Fields(line[7:])
gids = make([]int, len(f))
for i := range gids {
val, err := strconv.ParseInt(f[i], 10, 32)
if err != nil {
return nil
}
gids[i] = int(val)
}
return gids
}
}
return nil
}
// OpenatUser runs the Openat syscall in the context of a different user. // OpenatUser runs the Openat syscall in the context of a different user.
func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) { func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) {
if context != nil { if context != nil {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err = syscall.Setgroups(getSupplementaryGroups(context.Pid))
if err != nil {
return -1, err
}
defer syscall.Setgroups(nil)
err = syscall.Setregid(-1, int(context.Owner.Gid)) err = syscall.Setregid(-1, int(context.Owner.Gid))
if err != nil { if err != nil {
return -1, err return -1, err
@ -92,6 +127,12 @@ func MknodatUser(dirfd int, path string, mode uint32, dev int, context *fuse.Con
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err = syscall.Setgroups(getSupplementaryGroups(context.Pid))
if err != nil {
return err
}
defer syscall.Setgroups(nil)
err = syscall.Setregid(-1, int(context.Owner.Gid)) err = syscall.Setregid(-1, int(context.Owner.Gid))
if err != nil { if err != nil {
return err return err
@ -154,6 +195,12 @@ func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.C
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err = syscall.Setgroups(getSupplementaryGroups(context.Pid))
if err != nil {
return err
}
defer syscall.Setgroups(nil)
err = syscall.Setregid(-1, int(context.Owner.Gid)) err = syscall.Setregid(-1, int(context.Owner.Gid))
if err != nil { if err != nil {
return err return err
@ -176,6 +223,12 @@ func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (er
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err = syscall.Setgroups(getSupplementaryGroups(context.Pid))
if err != nil {
return err
}
defer syscall.Setgroups(nil)
err = syscall.Setregid(-1, int(context.Owner.Gid)) err = syscall.Setregid(-1, int(context.Owner.Gid))
if err != nil { if err != nil {
return err return err