summaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/opencontainers/runtime-tools/validate/validate.go')
-rw-r--r--vendor/github.com/opencontainers/runtime-tools/validate/validate.go312
1 files changed, 175 insertions, 137 deletions
diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go b/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
index bbdb29c60..0914bc691 100644
--- a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
+++ b/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
@@ -20,33 +20,41 @@ import (
"github.com/blang/semver"
"github.com/hashicorp/go-multierror"
rspec "github.com/opencontainers/runtime-spec/specs-go"
+ osFilepath "github.com/opencontainers/runtime-tools/filepath"
"github.com/sirupsen/logrus"
"github.com/syndtr/gocapability/capability"
"github.com/opencontainers/runtime-tools/specerror"
+ "github.com/xeipuuv/gojsonschema"
)
const specConfig = "config.json"
var (
- defaultRlimits = []string{
+ // http://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html
+ posixRlimits = []string{
"RLIMIT_AS",
"RLIMIT_CORE",
"RLIMIT_CPU",
"RLIMIT_DATA",
"RLIMIT_FSIZE",
- "RLIMIT_LOCKS",
+ "RLIMIT_NOFILE",
+ "RLIMIT_STACK",
+ }
+
+ // https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/getrlimit.2?h=man-pages-4.13
+ linuxRlimits = append(posixRlimits, []string{
"RLIMIT_MEMLOCK",
"RLIMIT_MSGQUEUE",
"RLIMIT_NICE",
- "RLIMIT_NOFILE",
"RLIMIT_NPROC",
"RLIMIT_RSS",
"RLIMIT_RTPRIO",
"RLIMIT_RTTIME",
"RLIMIT_SIGPENDING",
- "RLIMIT_STACK",
- }
+ }...)
+
+ configSchemaTemplate = "https://raw.githubusercontent.com/opencontainers/runtime-spec/v%s/schema/config-schema.json"
)
// Validator represents a validator for runtime bundle
@@ -86,7 +94,7 @@ func NewValidatorFromPath(bundlePath string, hostSpecific bool, platform string)
configPath := filepath.Join(bundlePath, specConfig)
content, err := ioutil.ReadFile(configPath)
if err != nil {
- return Validator{}, specerror.NewError(specerror.ConfigFileExistence, err, rspec.Version)
+ return Validator{}, specerror.NewError(specerror.ConfigInRootBundleDir, err, rspec.Version)
}
if !utf8.Valid(content) {
return Validator{}, fmt.Errorf("%q is not encoded in UTF-8", configPath)
@@ -100,7 +108,9 @@ func NewValidatorFromPath(bundlePath string, hostSpecific bool, platform string)
}
// CheckAll checks all parts of runtime bundle
-func (v *Validator) CheckAll() (errs error) {
+func (v *Validator) CheckAll() error {
+ var errs *multierror.Error
+ errs = multierror.Append(errs, v.CheckJSONSchema())
errs = multierror.Append(errs, v.CheckPlatform())
errs = multierror.Append(errs, v.CheckRoot())
errs = multierror.Append(errs, v.CheckMandatoryFields())
@@ -110,7 +120,50 @@ func (v *Validator) CheckAll() (errs error) {
errs = multierror.Append(errs, v.CheckHooks())
errs = multierror.Append(errs, v.CheckLinux())
- return
+ return errs.ErrorOrNil()
+}
+
+// JSONSchemaURL returns the URL for the JSON Schema specifying the
+// configuration format. It consumes configSchemaTemplate, but we
+// provide it as a function to isolate consumers from inconsistent
+// naming as runtime-spec evolves.
+func JSONSchemaURL(version string) (url string, err error) {
+ ver, err := semver.Parse(version)
+ if err != nil {
+ return "", specerror.NewError(specerror.SpecVersionInSemVer, err, rspec.Version)
+ }
+ configRenamedToConfigSchemaVersion, err := semver.Parse("1.0.0-rc2") // config.json became config-schema.json in 1.0.0-rc2
+ if ver.Compare(configRenamedToConfigSchemaVersion) == -1 {
+ return "", fmt.Errorf("unsupported configuration version (older than %s)", configRenamedToConfigSchemaVersion)
+ }
+ return fmt.Sprintf(configSchemaTemplate, version), nil
+}
+
+// CheckJSONSchema validates the configuration against the
+// runtime-spec JSON Schema, using the version of the schema that
+// matches the configuration's declared version.
+func (v *Validator) CheckJSONSchema() (errs error) {
+ url, err := JSONSchemaURL(v.spec.Version)
+ if err != nil {
+ errs = multierror.Append(errs, err)
+ return errs
+ }
+
+ schemaLoader := gojsonschema.NewReferenceLoader(url)
+ documentLoader := gojsonschema.NewGoLoader(v.spec)
+ result, err := gojsonschema.Validate(schemaLoader, documentLoader)
+ if err != nil {
+ errs = multierror.Append(errs, err)
+ return errs
+ }
+
+ if !result.Valid() {
+ for _, resultError := range result.Errors() {
+ errs = multierror.Append(errs, errors.New(resultError.String()))
+ }
+ }
+
+ return errs
}
// CheckRoot checks status of v.spec.Root
@@ -120,13 +173,30 @@ func (v *Validator) CheckRoot() (errs error) {
if v.platform == "windows" && v.spec.Windows != nil && v.spec.Windows.HyperV != nil {
if v.spec.Root != nil {
errs = multierror.Append(errs,
- specerror.NewError(specerror.RootOnHyperV, fmt.Errorf("for Hyper-V containers, Root must not be set"), rspec.Version))
+ specerror.NewError(specerror.RootOnHyperVNotSet, fmt.Errorf("for Hyper-V containers, Root must not be set"), rspec.Version))
return
}
return
} else if v.spec.Root == nil {
errs = multierror.Append(errs,
- specerror.NewError(specerror.RootOnNonHyperV, fmt.Errorf("for non-Hyper-V containers, Root must be set"), rspec.Version))
+ specerror.NewError(specerror.RootOnNonHyperVRequired, fmt.Errorf("for non-Hyper-V containers, Root must be set"), rspec.Version))
+ return
+ }
+
+ if v.platform == "windows" {
+ matched, err := regexp.MatchString(`\\\\[?]\\Volume[{][a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}[}]\\`, v.spec.Root.Path)
+ if err != nil {
+ errs = multierror.Append(errs, err)
+ } else if !matched {
+ errs = multierror.Append(errs,
+ specerror.NewError(specerror.RootPathOnWindowsGUID, fmt.Errorf("root.path is %q, but it MUST be a volume GUID path when target platform is windows", v.spec.Root.Path), rspec.Version))
+ }
+
+ if v.spec.Root.Readonly {
+ errs = multierror.Append(errs,
+ specerror.NewError(specerror.RootReadonlyOnWindowsFalse, fmt.Errorf("root.readonly field MUST be omitted or false when target platform is windows"), rspec.Version))
+ }
+
return
}
@@ -138,7 +208,7 @@ func (v *Validator) CheckRoot() (errs error) {
if filepath.Base(v.spec.Root.Path) != "rootfs" {
errs = multierror.Append(errs,
- specerror.NewError(specerror.PathName, fmt.Errorf("path name should be the conventional 'rootfs'"), rspec.Version))
+ specerror.NewError(specerror.RootPathOnPosixConvention, fmt.Errorf("path name should be the conventional 'rootfs'"), rspec.Version))
}
var rootfsPath string
@@ -158,10 +228,10 @@ func (v *Validator) CheckRoot() (errs error) {
if fi, err := os.Stat(rootfsPath); err != nil {
errs = multierror.Append(errs,
- specerror.NewError(specerror.PathExistence, fmt.Errorf("cannot find the root path %q", rootfsPath), rspec.Version))
+ specerror.NewError(specerror.RootPathExist, fmt.Errorf("cannot find the root path %q", rootfsPath), rspec.Version))
} else if !fi.IsDir() {
errs = multierror.Append(errs,
- specerror.NewError(specerror.PathExistence, fmt.Errorf("root.path %q is not a directory", rootfsPath), rspec.Version))
+ specerror.NewError(specerror.RootPathExist, fmt.Errorf("root.path %q is not a directory", rootfsPath), rspec.Version))
}
rootParent := filepath.Dir(absRootPath)
@@ -170,13 +240,6 @@ func (v *Validator) CheckRoot() (errs error) {
specerror.NewError(specerror.ArtifactsInSingleDir, fmt.Errorf("root.path is %q, but it MUST be a child of %q", v.spec.Root.Path, absBundlePath), rspec.Version))
}
- if v.platform == "windows" {
- if v.spec.Root.Readonly {
- errs = multierror.Append(errs,
- specerror.NewError(specerror.ReadonlyOnWindows, fmt.Errorf("root.readonly field MUST be omitted or false when target platform is windows"), rspec.Version))
- }
- }
-
return
}
@@ -188,7 +251,7 @@ func (v *Validator) CheckSemVer() (errs error) {
_, err := semver.Parse(version)
if err != nil {
errs = multierror.Append(errs,
- specerror.NewError(specerror.SpecVersion, fmt.Errorf("%q is not valid SemVer: %s", version, err.Error()), rspec.Version))
+ specerror.NewError(specerror.SpecVersionInSemVer, fmt.Errorf("%q is not valid SemVer: %s", version, err.Error()), rspec.Version))
}
if version != rspec.Version {
errs = multierror.Append(errs, fmt.Errorf("validate currently only handles version %s, but the supplied configuration targets %s", rspec.Version, version))
@@ -202,18 +265,23 @@ func (v *Validator) CheckHooks() (errs error) {
logrus.Debugf("check hooks")
if v.spec.Hooks != nil {
- errs = multierror.Append(errs, checkEventHooks("pre-start", v.spec.Hooks.Prestart, v.HostSpecific))
- errs = multierror.Append(errs, checkEventHooks("post-start", v.spec.Hooks.Poststart, v.HostSpecific))
- errs = multierror.Append(errs, checkEventHooks("post-stop", v.spec.Hooks.Poststop, v.HostSpecific))
+ errs = multierror.Append(errs, v.checkEventHooks("prestart", v.spec.Hooks.Prestart, v.HostSpecific))
+ errs = multierror.Append(errs, v.checkEventHooks("poststart", v.spec.Hooks.Poststart, v.HostSpecific))
+ errs = multierror.Append(errs, v.checkEventHooks("poststop", v.spec.Hooks.Poststop, v.HostSpecific))
}
return
}
-func checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (errs error) {
- for _, hook := range hooks {
- if !filepath.IsAbs(hook.Path) {
- errs = multierror.Append(errs, fmt.Errorf("the %s hook %v: is not absolute path", hookType, hook.Path))
+func (v *Validator) checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (errs error) {
+ for i, hook := range hooks {
+ if !osFilepath.IsAbs(v.platform, hook.Path) {
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.PosixHooksPathAbs,
+ fmt.Errorf("hooks.%s[%d].path %v: is not absolute path",
+ hookType, i, hook.Path),
+ rspec.Version))
}
if hostSpecific {
@@ -245,8 +313,12 @@ func (v *Validator) CheckProcess() (errs error) {
}
process := v.spec.Process
- if !filepath.IsAbs(process.Cwd) {
- errs = multierror.Append(errs, fmt.Errorf("cwd %q is not an absolute path", process.Cwd))
+ if !osFilepath.IsAbs(v.platform, process.Cwd) {
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.ProcCwdAbs,
+ fmt.Errorf("cwd %q is not an absolute path", process.Cwd),
+ rspec.Version))
}
for _, env := range process.Env {
@@ -256,7 +328,11 @@ func (v *Validator) CheckProcess() (errs error) {
}
if len(process.Args) == 0 {
- errs = multierror.Append(errs, fmt.Errorf("args must not be empty"))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.ProcArgsOneEntryRequired,
+ fmt.Errorf("args must not be empty"),
+ rspec.Version))
} else {
if filepath.IsAbs(process.Args[0]) {
var rootfsPath string
@@ -348,7 +424,7 @@ func (v *Validator) CheckCapabilities() (errs error) {
if effective && !permitted {
errs = multierror.Append(errs, fmt.Errorf("effective capability %q is not allowed, as it's not permitted", capability))
}
- if ambient && !(effective && inheritable) {
+ if ambient && !(permitted && inheritable) {
errs = multierror.Append(errs, fmt.Errorf("ambient capability %q is not allowed, as it's not permitted and inheribate", capability))
}
}
@@ -361,11 +437,20 @@ func (v *Validator) CheckCapabilities() (errs error) {
// CheckRlimits checks v.spec.Process.Rlimits
func (v *Validator) CheckRlimits() (errs error) {
+ if v.platform == "windows" {
+ return
+ }
+
process := v.spec.Process
for index, rlimit := range process.Rlimits {
for i := index + 1; i < len(process.Rlimits); i++ {
if process.Rlimits[index].Type == process.Rlimits[i].Type {
- errs = multierror.Append(errs, fmt.Errorf("rlimit can not contain the same type %q", process.Rlimits[index].Type))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.PosixProcRlimitsErrorOnDup,
+ fmt.Errorf("rlimit can not contain the same type %q",
+ process.Rlimits[index].Type),
+ rspec.Version))
}
}
errs = multierror.Append(errs, v.rlimitValid(rlimit))
@@ -429,31 +514,33 @@ func (v *Validator) CheckMounts() (errs error) {
if supportedTypes != nil && !supportedTypes[mountA.Type] {
errs = multierror.Append(errs, fmt.Errorf("unsupported mount type %q", mountA.Type))
}
- if v.platform == "windows" {
- if err := pathValid(v.platform, mountA.Destination); err != nil {
- errs = multierror.Append(errs, err)
- }
- if err := pathValid(v.platform, mountA.Source); err != nil {
- errs = multierror.Append(errs, err)
- }
- } else {
- if err := pathValid(v.platform, mountA.Destination); err != nil {
- errs = multierror.Append(errs, err)
- }
+ if !osFilepath.IsAbs(v.platform, mountA.Destination) {
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.MountsDestAbs,
+ fmt.Errorf("mounts[%d].destination %q is not absolute",
+ i,
+ mountA.Destination),
+ rspec.Version))
}
for j, mountB := range v.spec.Mounts {
if i == j {
continue
}
// whether B.Desination is nested within A.Destination
- nested, err := nestedValid(v.platform, mountA.Destination, mountB.Destination)
+ nested, err := osFilepath.IsAncestor(v.platform, mountA.Destination, mountB.Destination, ".")
if err != nil {
errs = multierror.Append(errs, err)
continue
}
if nested {
if v.platform == "windows" && i < j {
- errs = multierror.Append(errs, fmt.Errorf("on Windows, %v nested within %v is forbidden", mountB.Destination, mountA.Destination))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.MountsDestOnWindowsNotNested,
+ fmt.Errorf("on Windows, %v nested within %v is forbidden",
+ mountB.Destination, mountA.Destination),
+ rspec.Version))
}
if i > j {
logrus.Warnf("%v will be covered by %v", mountB.Destination, mountA.Destination)
@@ -476,7 +563,11 @@ func (v *Validator) CheckPlatform() (errs error) {
if v.platform == "windows" {
if v.spec.Windows == nil {
- errs = multierror.Append(errs, errors.New("'windows' MUST be set when platform is `windows`"))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.PlatformSpecConfOnWindowsSet,
+ fmt.Errorf("'windows' MUST be set when platform is `windows`"),
+ rspec.Version))
}
}
@@ -506,14 +597,14 @@ func (v *Validator) CheckLinux() (errs error) {
for index := 0; index < len(v.spec.Linux.Namespaces); index++ {
ns := v.spec.Linux.Namespaces[index]
- if !namespaceValid(ns) {
+ if !v.namespaceValid(ns) {
errs = multierror.Append(errs, fmt.Errorf("namespace %v is invalid", ns))
}
tmpItem := nsTypeList[ns.Type]
tmpItem.num = tmpItem.num + 1
if tmpItem.num > 1 {
- errs = multierror.Append(errs, fmt.Errorf("duplicated namespace %q", ns.Type))
+ errs = multierror.Append(errs, specerror.NewError(specerror.NSErrorOnDup, fmt.Errorf("duplicated namespace %q", ns.Type), rspec.Version))
}
if len(ns.Path) == 0 {
@@ -572,7 +663,8 @@ func (v *Validator) CheckLinux() (errs error) {
} else {
fStat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
- errs = multierror.Append(errs, fmt.Errorf("cannot determine state for device %s", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesAvailable,
+ fmt.Errorf("cannot determine state for device %s", device.Path), rspec.Version))
continue
}
var devType string
@@ -587,7 +679,8 @@ func (v *Validator) CheckLinux() (errs error) {
devType = "unmatched"
}
if devType != device.Type || (devType == "c" && device.Type == "u") {
- errs = multierror.Append(errs, fmt.Errorf("unmatched %s already exists in filesystem", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
+ fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
continue
}
if devType != "p" {
@@ -595,7 +688,8 @@ func (v *Validator) CheckLinux() (errs error) {
major := (dev >> 8) & 0xfff
minor := (dev & 0xff) | ((dev >> 12) & 0xfff00)
if int64(major) != device.Major || int64(minor) != device.Minor {
- errs = multierror.Append(errs, fmt.Errorf("unmatched %s already exists in filesystem", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
+ fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
continue
}
}
@@ -603,19 +697,22 @@ func (v *Validator) CheckLinux() (errs error) {
expectedPerm := *device.FileMode & os.ModePerm
actualPerm := fi.Mode() & os.ModePerm
if expectedPerm != actualPerm {
- errs = multierror.Append(errs, fmt.Errorf("unmatched %s already exists in filesystem", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
+ fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
continue
}
}
if device.UID != nil {
if *device.UID != fStat.Uid {
- errs = multierror.Append(errs, fmt.Errorf("unmatched %s already exists in filesystem", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
+ fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
continue
}
}
if device.GID != nil {
if *device.GID != fStat.Gid {
- errs = multierror.Append(errs, fmt.Errorf("unmatched %s already exists in filesystem", device.Path))
+ errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
+ fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
continue
}
}
@@ -645,29 +742,23 @@ func (v *Validator) CheckLinux() (errs error) {
errs = multierror.Append(errs, v.CheckSeccomp())
}
- switch v.spec.Linux.RootfsPropagation {
- case "":
- case "private":
- case "rprivate":
- case "slave":
- case "rslave":
- case "shared":
- case "rshared":
- case "unbindable":
- case "runbindable":
- default:
- errs = multierror.Append(errs, errors.New("rootfsPropagation must be empty or one of \"private|rprivate|slave|rslave|shared|rshared|unbindable|runbindable\""))
- }
-
for _, maskedPath := range v.spec.Linux.MaskedPaths {
if !strings.HasPrefix(maskedPath, "/") {
- errs = multierror.Append(errs, fmt.Errorf("maskedPath %v is not an absolute path", maskedPath))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.MaskedPathsAbs,
+ fmt.Errorf("maskedPath %v is not an absolute path", maskedPath),
+ rspec.Version))
}
}
for _, readonlyPath := range v.spec.Linux.ReadonlyPaths {
if !strings.HasPrefix(readonlyPath, "/") {
- errs = multierror.Append(errs, fmt.Errorf("readonlyPath %v is not an absolute path", readonlyPath))
+ errs = multierror.Append(errs,
+ specerror.NewError(
+ specerror.ReadonlyPathsAbs,
+ fmt.Errorf("readonlyPath %v is not an absolute path", readonlyPath),
+ rspec.Version))
}
}
@@ -709,7 +800,7 @@ func (v *Validator) CheckLinuxResources() (errs error) {
}
for index := 0; index < len(r.Devices); index++ {
switch r.Devices[index].Type {
- case "a", "b", "c":
+ case "a", "b", "c", "":
default:
errs = multierror.Append(errs, fmt.Errorf("type of devices %s is invalid", r.Devices[index].Type))
}
@@ -825,12 +916,19 @@ func (v *Validator) rlimitValid(rlimit rspec.POSIXRlimit) (errs error) {
}
if v.platform == "linux" {
- for _, val := range defaultRlimits {
+ for _, val := range linuxRlimits {
+ if val == rlimit.Type {
+ return
+ }
+ }
+ errs = multierror.Append(errs, specerror.NewError(specerror.PosixProcRlimitsTypeValueError, fmt.Errorf("rlimit type %q may not be valid", rlimit.Type), v.spec.Version))
+ } else if v.platform == "solaris" {
+ for _, val := range posixRlimits {
if val == rlimit.Type {
return
}
}
- errs = multierror.Append(errs, fmt.Errorf("rlimit type %q is invalid", rlimit.Type))
+ errs = multierror.Append(errs, specerror.NewError(specerror.PosixProcRlimitsTypeValueError, fmt.Errorf("rlimit type %q may not be valid", rlimit.Type), v.spec.Version))
} else {
logrus.Warnf("process.rlimits validation not yet implemented for platform %q", v.platform)
}
@@ -838,7 +936,7 @@ func (v *Validator) rlimitValid(rlimit rspec.POSIXRlimit) (errs error) {
return
}
-func namespaceValid(ns rspec.LinuxNamespace) bool {
+func (v *Validator) namespaceValid(ns rspec.LinuxNamespace) bool {
switch ns.Type {
case rspec.PIDNamespace:
case rspec.NetworkNamespace:
@@ -851,72 +949,13 @@ func namespaceValid(ns rspec.LinuxNamespace) bool {
return false
}
- if ns.Path != "" && !filepath.IsAbs(ns.Path) {
+ if ns.Path != "" && !osFilepath.IsAbs(v.platform, ns.Path) {
return false
}
return true
}
-func pathValid(os, path string) error {
- if os == "windows" {
- matched, err := regexp.MatchString("^[a-zA-Z]:(\\\\[^\\\\/<>|:*?\"]+)+$", path)
- if err != nil {
- return err
- }
- if !matched {
- return fmt.Errorf("invalid windows path %v", path)
- }
- return nil
- }
- if !filepath.IsAbs(path) {
- return fmt.Errorf("%v is not an absolute path", path)
- }
- return nil
-}
-
-// Check whether pathB is nested whithin pathA
-func nestedValid(os, pathA, pathB string) (bool, error) {
- if pathA == pathB {
- return false, nil
- }
- if pathA == "/" && pathB != "" {
- return true, nil
- }
-
- var sep string
- if os == "windows" {
- sep = "\\"
- } else {
- sep = "/"
- }
-
- splitedPathA := strings.Split(filepath.Clean(pathA), sep)
- splitedPathB := strings.Split(filepath.Clean(pathB), sep)
- lenA := len(splitedPathA)
- lenB := len(splitedPathB)
-
- if lenA > lenB {
- if (lenA - lenB) == 1 {
- // if pathA is longer but not end with separator
- if splitedPathA[lenA-1] != "" {
- return false, nil
- }
- splitedPathA = splitedPathA[:lenA-1]
- } else {
- return false, nil
- }
- }
-
- for i, partA := range splitedPathA {
- if partA != splitedPathB[i] {
- return false, nil
- }
- }
-
- return true, nil
-}
-
func deviceValid(d rspec.LinuxDevice) bool {
switch d.Type {
case "b", "c", "u":
@@ -924,7 +963,7 @@ func deviceValid(d rspec.LinuxDevice) bool {
return false
}
case "p":
- if d.Major > 0 || d.Minor > 0 {
+ if d.Major != 0 || d.Minor != 0 {
return false
}
default:
@@ -935,7 +974,6 @@ func deviceValid(d rspec.LinuxDevice) bool {
func seccompActionValid(secc rspec.LinuxSeccompAction) bool {
switch secc {
- case "":
case rspec.ActKill:
case rspec.ActTrap:
case rspec.ActErrno: