From 2f7fc0ff65b73cf2a6bfc1878aae75a7f5bae870 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 16 Nov 2017 13:16:30 +0100 Subject: pkg/kernel: sandbox make invocation --- pkg/osutil/osutil_linux.go | 64 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'pkg/osutil/osutil_linux.go') diff --git a/pkg/osutil/osutil_linux.go b/pkg/osutil/osutil_linux.go index 0a84f3f14..d2aa34f1f 100644 --- a/pkg/osutil/osutil_linux.go +++ b/pkg/osutil/osutil_linux.go @@ -6,11 +6,16 @@ package osutil import ( + "fmt" "io/ioutil" "os" "os/exec" "path/filepath" + "strconv" + "strings" + "sync" "syscall" + "time" "unsafe" ) @@ -27,10 +32,65 @@ func UmountAll(dir string) { } } +func Sandbox(cmd *exec.Cmd, user, net bool) error { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = new(syscall.SysProcAttr) + } + if user { + uid, err := initSandbox() + if err != nil { + return err + } + cmd.SysProcAttr.Credential = &syscall.Credential{ + Uid: uid, + Gid: uid, + } + } + if net { + cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC | + syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID + } + return nil +} + +func SandboxChown(file string) error { + uid, err := initSandbox() + if err != nil { + return err + } + return os.Chown(file, int(uid), int(uid)) +} + +var ( + sandboxOnce sync.Once + sandboxUsername = "syzkaller" + sandboxUID = ^uint32(0) +) + +func initSandbox() (uint32, error) { + sandboxOnce.Do(func() { + out, err := RunCmd(time.Minute, "", "id", "-u", sandboxUsername) + if err != nil || len(out) == 0 { + return + } + str := strings.Trim(string(out), " \t\n") + uid, err := strconv.ParseUint(str, 10, 32) + if err != nil { + return + } + sandboxUID = uint32(uid) + }) + if sandboxUID == ^uint32(0) { + return 0, fmt.Errorf("user %q is not found, can't sandbox command", sandboxUsername) + } + return sandboxUID, nil +} + func setPdeathsig(cmd *exec.Cmd) { - cmd.SysProcAttr = &syscall.SysProcAttr{ - Pdeathsig: syscall.SIGKILL, + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = new(syscall.SysProcAttr) } + cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL } func prolongPipe(r, w *os.File) { -- cgit mrf-deployment