diff options
| author | Sebastian Lackner | 2019-05-01 13:18:44 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2019-05-01 17:52:07 +0200 | 
| commit | a97d14c42d902e53efdb42e9b32c4a39559fc262 (patch) | |
| tree | 6849755b938c89c2c458f10b3ee428dbf6dbebfd /internal/syscallcompat | |
| parent | 96935e16b9167dc3c472505872b3fc5235203a05 (diff) | |
syscallcompat: fetch supplementary groups for OpenatUser & friends
Handled the same way in GlusterFS, disorderfs, libfuse.
Fixes https://github.com/rfjakob/gocryptfs/issues/394
Diffstat (limited to 'internal/syscallcompat')
| -rw-r--r-- | internal/syscallcompat/sys_linux.go | 53 | 
1 files changed, 53 insertions, 0 deletions
| diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go index 92d8183..ac7891a 100644 --- a/internal/syscallcompat/sys_linux.go +++ b/internal/syscallcompat/sys_linux.go @@ -3,7 +3,10 @@ package syscallcompat  import (  	"fmt" +	"io/ioutil"  	"runtime" +	"strconv" +	"strings"  	"sync"  	"syscall"  	"time" @@ -59,12 +62,44 @@ func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {  	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.  func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) {  	if context != nil {  		runtime.LockOSThread()  		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))  		if err != nil {  			return -1, err @@ -92,6 +127,12 @@ func MknodatUser(dirfd int, path string, mode uint32, dev int, context *fuse.Con  		runtime.LockOSThread()  		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))  		if err != nil {  			return err @@ -154,6 +195,12 @@ func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.C  		runtime.LockOSThread()  		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))  		if err != nil {  			return err @@ -176,6 +223,12 @@ func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (er  		runtime.LockOSThread()  		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))  		if err != nil {  			return err | 
