summaryrefslogtreecommitdiffhomepage
path: root/runsc/container
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-05-24 14:27:05 -0700
committerShentubot <shentubot@google.com>2018-05-24 14:27:57 -0700
commite48f7078761b00552ac74068c184ee4fb90fe9aa (patch)
tree8cb4ff41119d6fa8c28ed11d33f350bae4321ad1 /runsc/container
parent7996ae7ccf284718fc98f5ba34c94b044b858ec2 (diff)
Configure sandbox as superuser
Container user might not have enough priviledge to walk directories and mount filesystems. Instead, create superuser to perform these steps of the configuration. PiperOrigin-RevId: 197953667 Change-Id: I643650ab654e665408e2af1b8e2f2aa12d58d4fb
Diffstat (limited to 'runsc/container')
-rw-r--r--runsc/container/container_test.go106
1 files changed, 73 insertions, 33 deletions
diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go
index e1674d631..24e9de3ce 100644
--- a/runsc/container/container_test.go
+++ b/runsc/container/container_test.go
@@ -20,6 +20,7 @@ import (
"io"
"io/ioutil"
"os"
+ "path"
"path/filepath"
"reflect"
"strings"
@@ -132,6 +133,34 @@ func waitForProcessList(s *container.Container, expected []*control.Process) err
return fmt.Errorf("container got process list: %s, want: %s", procListToString(got), procListToString(expected))
}
+// procListsEqual is used to check whether 2 Process lists are equal for all
+// implemented fields.
+func procListsEqual(got, want []*control.Process) bool {
+ if len(got) != len(want) {
+ return false
+ }
+ for i := range got {
+ pd1 := got[i]
+ pd2 := want[i]
+ // Zero out unimplemented and timing dependant fields.
+ pd1.Time, pd2.Time = "", ""
+ pd1.STime, pd2.STime = "", ""
+ pd1.C, pd2.C = 0, 0
+ if *pd1 != *pd2 {
+ return false
+ }
+ }
+ return true
+}
+
+func procListToString(pl []*control.Process) string {
+ strs := make([]string, 0, len(pl))
+ for _, p := range pl {
+ strs = append(strs, fmt.Sprintf("%+v", p))
+ }
+ return fmt.Sprintf("[%s]", strings.Join(strs, ","))
+}
+
// TestLifecycle tests the basic Create/Start/Signal/Destroy container lifecycle.
// It verifies after each step that the container can be loaded from disk, and
// has the correct status.
@@ -434,17 +463,6 @@ func TestCapabilities(t *testing.T) {
Type: "bind",
})
- // Capability below is needed to mount TempDir above in case the user doesn't
- // have access to all parents that lead to TempDir.
- caps := []string{"CAP_DAC_OVERRIDE"}
- spec.Process.Capabilities = &specs.LinuxCapabilities{
- Bounding: caps,
- Effective: caps,
- Inheritable: caps,
- Permitted: caps,
- Ambient: caps,
- }
-
rootDir, bundleDir, conf, err := setupContainer(spec)
if err != nil {
t.Fatalf("error setting up container: %v", err)
@@ -621,32 +639,54 @@ func TestSpecUnsupported(t *testing.T) {
}
}
-// procListsEqual is used to check whether 2 Process lists are equal for all
-// implemented fields.
-func procListsEqual(got, want []*control.Process) bool {
- if len(got) != len(want) {
- return false
+// TestRunNonRoot checks that sandbox can be configured when running as
+// non-priviledged user.
+func TestRunNonRoot(t *testing.T) {
+ spec := newSpecWithArgs("/bin/true")
+ spec.Process.User.UID = 343
+ spec.Process.User.GID = 2401
+
+ // User that container runs as can't list '$TMP/blocked' and would fail to
+ // mount it.
+ dir := path.Join(os.TempDir(), "blocked")
+ if err := os.Mkdir(dir, 0700); err != nil {
+ t.Fatalf("os.MkDir(%q) failed: %v", dir, err)
}
- for i := range got {
- pd1 := got[i]
- pd2 := want[i]
- // Zero out unimplemented and timing dependant fields.
- pd1.Time, pd2.Time = "", ""
- pd1.STime, pd2.STime = "", ""
- pd1.C, pd2.C = 0, 0
- if *pd1 != *pd2 {
- return false
- }
+ dir = path.Join(dir, "test")
+ if err := os.Mkdir(dir, 0755); err != nil {
+ t.Fatalf("os.MkDir(%q) failed: %v", dir, err)
}
- return true
-}
-func procListToString(pl []*control.Process) string {
- strs := make([]string, 0, len(pl))
- for _, p := range pl {
- strs = append(strs, fmt.Sprintf("%+v", p))
+ // We generate files in the host temporary directory.
+ spec.Mounts = append(spec.Mounts, specs.Mount{
+ Destination: dir,
+ Source: dir,
+ Type: "bind",
+ })
+
+ rootDir, bundleDir, conf, err := setupContainer(spec)
+ if err != nil {
+ t.Fatalf("error setting up container: %v", err)
+ }
+ defer os.RemoveAll(rootDir)
+ defer os.RemoveAll(bundleDir)
+
+ // Create, start and wait for the container.
+ s, err := container.Create(uniqueContainerID(), spec, conf, bundleDir, "", "")
+ if err != nil {
+ t.Fatalf("error creating container: %v", err)
+ }
+ defer s.Destroy()
+ if err := s.Start(conf); err != nil {
+ t.Fatalf("error starting container: %v", err)
+ }
+ ws, err := s.Wait()
+ if err != nil {
+ t.Errorf("error waiting on container: %v", err)
+ }
+ if !ws.Exited() || ws.ExitStatus() != 0 {
+ t.Errorf("container failed, waitStatus: %v", ws)
}
- return fmt.Sprintf("[%s]", strings.Join(strs, ","))
}
// TestMain acts like runsc if it is called with the "boot" argument, otherwise