summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-06-04 11:51:27 -0700
committerShentubot <shentubot@google.com>2018-06-04 11:52:17 -0700
commit55a37ceef1e33cc72236db6e95f159963ddf40bd (patch)
tree2dadd3fa65b3cba4e756a6c63e2e61af5dc2320f /runsc/sandbox
parenta0e2126be49e5eda45dcaead497129c08e08a1e5 (diff)
Fix leaky FD
9P socket was being created without CLOEXEC and was being inherited by the children. This would prevent the gofer from detecting that the sandbox had exited, because the socket would not be closed. PiperOrigin-RevId: 199168959 Change-Id: I3ee1a07cbe7331b0aeb1cf2b697e728ce24f85a7
Diffstat (limited to 'runsc/sandbox')
-rw-r--r--runsc/sandbox/BUILD16
-rw-r--r--runsc/sandbox/sandbox.go2
-rw-r--r--runsc/sandbox/sandbox_test.go74
3 files changed, 90 insertions, 2 deletions
diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD
index e89b19552..a961c3cc7 100644
--- a/runsc/sandbox/BUILD
+++ b/runsc/sandbox/BUILD
@@ -1,6 +1,6 @@
package(licenses = ["notice"]) # Apache 2.0
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "sandbox",
@@ -28,3 +28,17 @@ go_library(
"@org_golang_x_sys//unix:go_default_library",
],
)
+
+go_test(
+ name = "sandbox_test",
+ size = "small",
+ srcs = ["sandbox_test.go"],
+ data = [
+ "//runsc",
+ ],
+ embed = [":sandbox"],
+ deps = [
+ "//pkg/log",
+ "//runsc/test/testutil",
+ ],
+)
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index a9486cfdc..91c44c996 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -195,7 +195,7 @@ func (s *Sandbox) createGoferProcess(spec *specs.Spec, conf *boot.Config, bundle
goferEnds := make([]*os.File, 0, mountCount)
for i := 0; i < mountCount; i++ {
// Create socket that connects the sandbox and gofer.
- fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
+ fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
if err != nil {
return nil, err
}
diff --git a/runsc/sandbox/sandbox_test.go b/runsc/sandbox/sandbox_test.go
new file mode 100644
index 000000000..e25290d5e
--- /dev/null
+++ b/runsc/sandbox/sandbox_test.go
@@ -0,0 +1,74 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sandbox
+
+import (
+ "os"
+ "testing"
+
+ "gvisor.googlesource.com/gvisor/pkg/log"
+ "gvisor.googlesource.com/gvisor/runsc/test/testutil"
+)
+
+func init() {
+ log.SetLevel(log.Debug)
+ if err := testutil.ConfigureExePath(); err != nil {
+ panic(err.Error())
+ }
+}
+
+func TestGoferExits(t *testing.T) {
+ spec := testutil.NewSpecWithArgs("/bin/sleep", "10000")
+ rootDir, bundleDir, conf, err := testutil.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 := Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "")
+ if err != nil {
+ t.Fatalf("error creating container: %v", err)
+ }
+ defer s.Destroy()
+ if err := s.Start("123", spec, conf); err != nil {
+ t.Fatalf("error starting container: %v", err)
+ }
+
+ sandboxProc, err := os.FindProcess(s.Pid)
+ if err != nil {
+ t.Fatalf("error finding sandbox process: %v", err)
+ }
+ gofer, err := os.FindProcess(s.GoferPid)
+ if err != nil {
+ t.Fatalf("error finding sandbox process: %v", err)
+ }
+
+ // Kill sandbox and expect gofer to exit on its own.
+ if err := sandboxProc.Kill(); err != nil {
+ t.Fatalf("error killing sandbox process: %v", err)
+ }
+ if _, err := sandboxProc.Wait(); err != nil {
+ t.Fatalf("error waiting for sandbox process: %v", err)
+ }
+
+ if _, err := gofer.Wait(); err != nil {
+ t.Fatalf("error waiting for gofer process: %v", err)
+ }
+ if s.IsRunning() {
+ t.Errorf("Sandbox shouldn't be running, sandbox: %+v", s)
+ }
+}