From 9ae4e28f75979905a6396962a232e217323499f9 Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Tue, 4 Sep 2018 13:36:26 -0700 Subject: runsc: fix container rootfs path. PiperOrigin-RevId: 211515350 Change-Id: Ia495af57447c799909aa97bb873a50b87bee2625 --- runsc/specutils/specutils.go | 26 ++++++++++++++++++++++++++ runsc/specutils/specutils_test.go | 22 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'runsc/specutils') 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 { -- cgit v1.2.3