diff options
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 | 
