summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLantao Liu <lantaol@google.com>2018-09-04 13:36:26 -0700
committerShentubot <shentubot@google.com>2018-09-04 13:37:40 -0700
commit9ae4e28f75979905a6396962a232e217323499f9 (patch)
tree2af27d93429e174aae3d05686aac87c897d4252e
parent3944cb41cbef64ac507e87f258441000a46424d5 (diff)
runsc: fix container rootfs path.
PiperOrigin-RevId: 211515350 Change-Id: Ia495af57447c799909aa97bb873a50b87bee2625
-rw-r--r--runsc/cmd/boot.go8
-rw-r--r--runsc/cmd/gofer.go6
-rw-r--r--runsc/cmd/path.go10
-rw-r--r--runsc/container/fs.go6
-rw-r--r--runsc/specutils/specutils.go26
-rw-r--r--runsc/specutils/specutils_test.go22
6 files changed, 49 insertions, 29 deletions
diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go
index 4e08dafc8..666be902a 100644
--- a/runsc/cmd/boot.go
+++ b/runsc/cmd/boot.go
@@ -93,14 +93,6 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
}
specutils.LogSpec(spec)
- // Turn any relative paths in the spec to absolute by prepending the bundleDir.
- spec.Root.Path = absPath(b.bundleDir, spec.Root.Path)
- for _, m := range spec.Mounts {
- if m.Source != "" {
- m.Source = absPath(b.bundleDir, m.Source)
- }
- }
-
conf := args[0].(*boot.Config)
waitStatus := args[1].(*syscall.WaitStatus)
diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go
index f28e02798..95926f5f9 100644
--- a/runsc/cmd/gofer.go
+++ b/runsc/cmd/gofer.go
@@ -16,7 +16,6 @@ package cmd
import (
"os"
- "path"
"sync"
"syscall"
@@ -108,7 +107,7 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
syscall.Umask(0)
// Find what path is going to be served by this gofer.
- root := absPath(g.bundleDir, spec.Root.Path)
+ root := spec.Root.Path
if err := syscall.Chroot(root); err != nil {
Fatalf("failed to chroot to %q: %v", root, err)
}
@@ -131,9 +130,6 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
mountIdx := 1 // first one is the root
for _, m := range spec.Mounts {
if specutils.Is9PMount(m) {
- if !path.IsAbs(m.Destination) {
- Fatalf("destination must be absolute path: %v", m.Destination)
- }
cfg := fsgofer.Config{
ROMount: isReadonlyMount(m.Options),
PanicOnWrite: g.panicOnWrite,
diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go
index 4bb1dbb4f..c207b80da 100644
--- a/runsc/cmd/path.go
+++ b/runsc/cmd/path.go
@@ -16,18 +16,8 @@ package cmd
import (
"os"
- "path/filepath"
)
-// absPath turns the given path into an absolute path (if it is not already
-// absolute) by prepending the base path.
-func absPath(base, rel string) string {
- if filepath.IsAbs(rel) {
- return rel
- }
- return filepath.Join(base, rel)
-}
-
// getwdOrDie returns the current working directory and dies if it cannot.
func getwdOrDie() string {
wd, err := os.Getwd()
diff --git a/runsc/container/fs.go b/runsc/container/fs.go
index b93c866ea..fb352fc7c 100644
--- a/runsc/container/fs.go
+++ b/runsc/container/fs.go
@@ -78,9 +78,6 @@ func setupFS(spec *specs.Spec, conf *boot.Config, bundleDir string) error {
continue
}
src := m.Source
- if !filepath.IsAbs(src) {
- src = filepath.Join(bundleDir, src)
- }
srcfi, err := os.Stat(src)
if err != nil {
return fmt.Errorf("failed to stat() mount source: %v", err)
@@ -130,9 +127,6 @@ func setupFS(spec *specs.Spec, conf *boot.Config, bundleDir string) error {
log.Infof("Remounting root as readonly: %q", spec.Root.Path)
flags := uintptr(syscall.MS_BIND | syscall.MS_REMOUNT | syscall.MS_RDONLY | syscall.MS_REC)
src := spec.Root.Path
- if !filepath.IsAbs(src) {
- src = filepath.Join(bundleDir, src)
- }
if err := syscall.Mount(src, src, "bind", flags, ""); err != nil {
return fmt.Errorf("failed to remount root as readonly with source: %q, target: %q, flags: %#x, err: %v", spec.Root.Path, spec.Root.Path, flags, err)
}
diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go
index 5fb53edb2..6c1ac56c3 100644
--- a/runsc/specutils/specutils.go
+++ b/runsc/specutils/specutils.go
@@ -21,6 +21,7 @@ import (
"fmt"
"io/ioutil"
"os"
+ "path"
"path/filepath"
"strings"
"syscall"
@@ -83,6 +84,12 @@ func ValidateSpec(spec *specs.Spec) error {
log.Warningf("Seccomp spec is being ignored")
}
+ for i, m := range spec.Mounts {
+ if !path.IsAbs(m.Destination) {
+ return fmt.Errorf("Spec.Mounts[%d] Mount.Destination must be an absolute path: %v", i, m)
+ }
+ }
+
// Two annotations are use by containerd to support multi-container pods.
// "io.kubernetes.cri.container-type"
// "io.kubernetes.cri.sandbox-id"
@@ -105,7 +112,18 @@ func ValidateSpec(spec *specs.Spec) error {
return nil
}
+// absPath turns the given path into an absolute path (if it is not already
+// absolute) by prepending the base path.
+func absPath(base, rel string) string {
+ if filepath.IsAbs(rel) {
+ return rel
+ }
+ return filepath.Join(base, rel)
+}
+
// ReadSpec reads an OCI runtime spec from the given bundle directory.
+// ReadSpec also normalizes all potential relative paths into absolute
+// path, e.g. spec.Root.Path, mount.Source.
func ReadSpec(bundleDir string) (*specs.Spec, error) {
// The spec file must be in "config.json" inside the bundle directory.
specFile := filepath.Join(bundleDir, "config.json")
@@ -120,6 +138,14 @@ func ReadSpec(bundleDir string) (*specs.Spec, error) {
if err := ValidateSpec(&spec); err != nil {
return nil, err
}
+ // Turn any relative paths in the spec to absolute by prepending the bundleDir.
+ spec.Root.Path = absPath(bundleDir, spec.Root.Path)
+ for i := range spec.Mounts {
+ m := &spec.Mounts[i]
+ if m.Source != "" {
+ m.Source = absPath(bundleDir, m.Source)
+ }
+ }
return &spec, nil
}
diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go
index 2c4e3e729..64e2172c8 100644
--- a/runsc/specutils/specutils_test.go
+++ b/runsc/specutils/specutils_test.go
@@ -113,6 +113,12 @@ func TestSpecInvalid(t *testing.T) {
Process: &specs.Process{
Args: []string{"/bin/true"},
},
+ Mounts: []specs.Mount{
+ {
+ Source: "src",
+ Destination: "/dst",
+ },
+ },
},
error: "",
},
@@ -197,6 +203,22 @@ func TestSpecInvalid(t *testing.T) {
},
error: "is not supported",
},
+ {
+ name: "relative mount destination",
+ spec: specs.Spec{
+ Root: &specs.Root{Path: "/"},
+ Process: &specs.Process{
+ Args: []string{"/bin/true"},
+ },
+ Mounts: []specs.Mount{
+ {
+ Source: "src",
+ Destination: "dst",
+ },
+ },
+ },
+ error: "must be an absolute path",
+ },
} {
err := ValidateSpec(&test.spec)
if len(test.error) == 0 {