diff --git a/libcontainer/configs/validate/validator.go b/libcontainer/configs/validate/validator.go index 3d736cff268..e0fcdf76931 100644 --- a/libcontainer/configs/validate/validator.go +++ b/libcontainer/configs/validate/validator.go @@ -25,6 +25,9 @@ func (v *ConfigValidator) Validate(config *configs.Config) error { if err := v.rootfs(config); err != nil { return err } + if err := v.mounts(config); err != nil { + return err + } if err := v.network(config); err != nil { return err } @@ -65,6 +68,29 @@ func (v *ConfigValidator) rootfs(config *configs.Config) error { return nil } +// mounts validates that the config actually has all of the required +// mountpoints as specified by the runtime-spec (config-linux.md#default-filesystems). +func (v *ConfigValidator) mounts(config *configs.Config) error { + if !config.Namespaces.Contains(configs.NEWNS) { + // No mount namespace, nothing to check. + return nil + } + + dests := map[string]bool{} + for _, mount := range config.Mounts { + dests[filepath.Clean(mount.Destination)] = true + } + + // From the spec. + for _, mountpoint := range []string{"/proc", "/sys", "/dev/shm", "/dev/pts"} { + if ok := dests[mountpoint]; !ok { + return fmt.Errorf("mount config is missing required filesystem: %s", mountpoint) + } + } + + return nil +} + func (v *ConfigValidator) network(config *configs.Config) error { if !config.Namespaces.Contains(configs.NEWNET) { if len(config.Networks) > 0 || len(config.Routes) > 0 { diff --git a/libcontainer/configs/validate/validator_test.go b/libcontainer/configs/validate/validator_test.go index f6826fb3efc..ec5beb8a36c 100644 --- a/libcontainer/configs/validate/validator_test.go +++ b/libcontainer/configs/validate/validator_test.go @@ -106,6 +106,13 @@ func TestValidateSecurityWithMaskPaths(t *testing.T) { {Type: configs.NEWNS}, }, ), + // Required to pass mount validation. + Mounts: []*configs.Mount{ + {Destination: "/proc"}, + {Destination: "/sys"}, + {Destination: "/dev/shm"}, + {Destination: "/dev/pts"}, + }, } validator := validate.New() @@ -124,6 +131,13 @@ func TestValidateSecurityWithROPaths(t *testing.T) { {Type: configs.NEWNS}, }, ), + // Required to pass mount validation. + Mounts: []*configs.Mount{ + {Destination: "/proc"}, + {Destination: "/sys"}, + {Destination: "/dev/shm"}, + {Destination: "/dev/pts"}, + }, } validator := validate.New()