diff options
-rw-r--r-- | runsc/cmd/boot.go | 8 | ||||
-rw-r--r-- | runsc/cmd/gofer.go | 6 | ||||
-rw-r--r-- | runsc/cmd/path.go | 10 | ||||
-rw-r--r-- | runsc/container/fs.go | 6 | ||||
-rw-r--r-- | runsc/specutils/specutils.go | 26 | ||||
-rw-r--r-- | runsc/specutils/specutils_test.go | 22 |
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 { |