summaryrefslogtreecommitdiffhomepage
path: root/runsc/test/testutil
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-08-27 11:09:06 -0700
committerShentubot <shentubot@google.com>2018-08-27 11:10:14 -0700
commitdb81c0b02f2f947ae837a3e16471a148a66436eb (patch)
treed91ef12da80b0a76ef1c69db290665e31cc59860 /runsc/test/testutil
parent2524111fc63343fd7372f5ea0266130adea778a5 (diff)
Put fsgofer inside chroot
Now each container gets its own dedicated gofer that is chroot'd to the rootfs path. This is done to add an extra layer of security in case the gofer gets compromised. PiperOrigin-RevId: 210396476 Change-Id: Iba21360a59dfe90875d61000db103f8609157ca0
Diffstat (limited to 'runsc/test/testutil')
-rw-r--r--runsc/test/testutil/BUILD1
-rw-r--r--runsc/test/testutil/docker.go6
-rw-r--r--runsc/test/testutil/testutil.go57
3 files changed, 61 insertions, 3 deletions
diff --git a/runsc/test/testutil/BUILD b/runsc/test/testutil/BUILD
index 03ab3c4ac..ca91e07ff 100644
--- a/runsc/test/testutil/BUILD
+++ b/runsc/test/testutil/BUILD
@@ -18,5 +18,6 @@ go_library(
"//runsc/specutils",
"@com_github_cenkalti_backoff//:go_default_library",
"@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
+ "@com_github_syndtr_gocapability//capability:go_default_library",
],
)
diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go
index b7d60e712..fc67c174a 100644
--- a/runsc/test/testutil/docker.go
+++ b/runsc/test/testutil/docker.go
@@ -32,7 +32,7 @@ func init() {
rand.Seed(time.Now().UnixNano())
}
-func runtime() string {
+func getRuntime() string {
r := os.Getenv("RUNSC_RUNTIME")
if r == "" {
return "runsc-test"
@@ -43,7 +43,7 @@ func runtime() string {
// IsPauseResumeSupported returns true if Pause/Resume is supported by runtime.
func IsPauseResumeSupported() bool {
// Native host network stack can't be saved.
- return !strings.Contains(runtime(), "hostnet")
+ return !strings.Contains(getRuntime(), "hostnet")
}
// EnsureSupportedDockerVersion checks if correct docker is installed.
@@ -128,7 +128,7 @@ type Docker struct {
// Names of containers will be unique.
func MakeDocker(namePrefix string) Docker {
suffix := fmt.Sprintf("-%06d", rand.Int())[:7]
- return Docker{Name: namePrefix + suffix, Runtime: runtime()}
+ return Docker{Name: namePrefix + suffix, Runtime: getRuntime()}
}
// Create calls 'docker create' with the arguments provided.
diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go
index fc3d61e52..e90ab5ad5 100644
--- a/runsc/test/testutil/testutil.go
+++ b/runsc/test/testutil/testutil.go
@@ -23,11 +23,16 @@ import (
"io/ioutil"
"net/http"
"os"
+ "os/exec"
"path/filepath"
+ "runtime"
+ "syscall"
+ "testing"
"time"
"github.com/cenkalti/backoff"
specs "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/syndtr/gocapability/capability"
"gvisor.googlesource.com/gvisor/runsc/boot"
"gvisor.googlesource.com/gvisor/runsc/specutils"
)
@@ -227,3 +232,55 @@ func WaitForHTTP(port int, timeout time.Duration) error {
}
return Poll(cb, timeout)
}
+
+// RunAsRoot ensures the test runs with CAP_SYS_ADMIN. If need it will create
+// a new user namespace and reexecute the test as root inside of the namespace.
+func RunAsRoot(m *testing.M) {
+ caps, err := capability.NewPid2(os.Getpid())
+ if err != nil {
+ panic(err.Error())
+ }
+ if err := caps.Load(); err != nil {
+ panic(err.Error())
+ }
+ if caps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) {
+ // Capability: check! Good to run.
+ os.Exit(m.Run())
+ }
+
+ // Current process doesn't have CAP_SYS_ADMIN, create user namespace and run
+ // as root inside that namespace to get it.
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ cmd := exec.Command("/proc/self/exe", os.Args...)
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Cloneflags: syscall.CLONE_NEWUSER | syscall.CLONE_NEWNS,
+ // Set current user/group as root inside the namespace.
+ UidMappings: []syscall.SysProcIDMap{
+ {ContainerID: 0, HostID: os.Getuid(), Size: 1},
+ },
+ GidMappings: []syscall.SysProcIDMap{
+ {ContainerID: 0, HostID: os.Getgid(), Size: 1},
+ },
+ GidMappingsEnableSetgroups: false,
+ Credential: &syscall.Credential{
+ Uid: 0,
+ Gid: 0,
+ },
+ }
+ cmd.Env = os.Environ()
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ if exit, ok := err.(*exec.ExitError); ok {
+ if ws, ok := exit.Sys().(syscall.WaitStatus); ok {
+ os.Exit(ws.ExitStatus())
+ }
+ os.Exit(-1)
+ }
+ panic(fmt.Sprint("error running child process:", err.Error()))
+ }
+ os.Exit(0)
+}