diff options
author | Fabricio Voznika <fvoznika@google.com> | 2019-03-18 12:29:43 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-03-18 12:30:43 -0700 |
commit | e420cc3e5d2066674d32d16ad885bee6b30da210 (patch) | |
tree | 991b119af7c8816a539318560338b3e5f065a2f8 /runsc/specutils/specutils.go | |
parent | eb69542807a87491fd4e6405bdab1c0f64db536d (diff) |
Add support for mount propagation
Properly handle propagation options for root and mounts. Now usage of
mount options shared, rshared, and noexec cause error to start. shared/
rshared breaks sandbox=>host isolation. slave however can be supported
because changes propagate from host to sandbox.
Root FS setup moved inside the gofer. Apart from simplifying the code,
it keeps all mounts inside the namespace. And they are torn down when
the namespace is destroyed (DestroyFS is no longer needed).
PiperOrigin-RevId: 239037661
Change-Id: I8b5ee4d50da33c042ea34fa68e56514ebe20e6e0
Diffstat (limited to 'runsc/specutils/specutils.go')
-rw-r--r-- | runsc/specutils/specutils.go | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index 4e7893ab4..cbf099c64 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -92,9 +92,14 @@ 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) + if spec.Linux != nil && spec.Linux.RootfsPropagation != "" { + if err := validateRootfsPropagation(spec.Linux.RootfsPropagation); err != nil { + return err + } + } + for _, m := range spec.Mounts { + if err := validateMount(&m); err != nil { + return err } } @@ -129,15 +134,19 @@ func absPath(base, rel string) string { return filepath.Join(base, rel) } +// OpenSpec opens an OCI runtime spec from the given bundle directory. +func OpenSpec(bundleDir string) (*os.File, error) { + // The spec file must be named "config.json" inside the bundle directory. + return os.Open(filepath.Join(bundleDir, "config.json")) +} + // 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. - specPath := filepath.Join(bundleDir, "config.json") - specFile, err := os.Open(specPath) + specFile, err := OpenSpec(bundleDir) if err != nil { - return nil, fmt.Errorf("error opening spec file %q: %v", specPath, err) + return nil, fmt.Errorf("error opening spec file %q: %v", specFile.Name(), err) } defer specFile.Close() return ReadSpecFromFile(bundleDir, specFile) @@ -171,27 +180,17 @@ func ReadSpecFromFile(bundleDir string, specFile *os.File) (*specs.Spec, error) return &spec, nil } -// OpenCleanSpec opens spec file that has destination mount paths resolved to -// their absolute location. -func OpenCleanSpec(bundleDir string) (*os.File, error) { - f, err := os.Open(filepath.Join(bundleDir, "config.clean.json")) +// ReadMounts reads mount list from a file. +func ReadMounts(f *os.File) ([]specs.Mount, error) { + bytes, err := ioutil.ReadAll(f) if err != nil { - return nil, err + return nil, fmt.Errorf("error reading mounts: %v", err) } - if _, err := f.Seek(0, os.SEEK_SET); err != nil { - f.Close() - return nil, fmt.Errorf("error seeking to beginning of file %q: %v", f.Name(), err) - } - return f, nil -} - -// WriteCleanSpec writes a spec file that has destination mount paths resolved. -func WriteCleanSpec(bundleDir string, spec *specs.Spec) error { - bytes, err := json.Marshal(spec) - if err != nil { - return err + var mounts []specs.Mount + if err := json.Unmarshal(bytes, &mounts); err != nil { + return nil, fmt.Errorf("error unmarshaling mounts: %v\n %s", err, string(bytes)) } - return ioutil.WriteFile(filepath.Join(bundleDir, "config.clean.json"), bytes, 0755) + return mounts, nil } // Capabilities takes in spec and returns a TaskCapabilities corresponding to @@ -407,8 +406,7 @@ func Mount(src, dst, typ string, flags uint32) error { // source (file or directory). var isDir bool if typ == "proc" { - // Special case, as there is no source directory for proc - // mounts. + // Special case, as there is no source directory for proc mounts. isDir = true } else if fi, err := os.Stat(src); err != nil { return fmt.Errorf("Stat(%q) failed: %v", src, err) |