Skip to content
This repository was archived by the owner on Apr 21, 2021. It is now read-only.

Commit 34d0d59

Browse files
author
Zhou Hao
authored
Merge pull request opencontainers#560 from vbatts/platform
validate: CheckLinux is platform dependent
2 parents 444b996 + 3401d41 commit 34d0d59

File tree

3 files changed

+201
-184
lines changed

3 files changed

+201
-184
lines changed

validate/validate.go

Lines changed: 0 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"regexp"
1414
"runtime"
1515
"strings"
16-
"syscall"
1716
"unicode"
1817
"unicode/utf8"
1918

@@ -590,189 +589,6 @@ func (v *Validator) CheckPlatform() (errs error) {
590589
return
591590
}
592591

593-
// CheckLinux checks v.spec.Linux
594-
func (v *Validator) CheckLinux() (errs error) {
595-
logrus.Debugf("check linux")
596-
597-
if v.spec.Linux == nil {
598-
return
599-
}
600-
601-
var nsTypeList = map[rspec.LinuxNamespaceType]struct {
602-
num int
603-
newExist bool
604-
}{
605-
rspec.PIDNamespace: {0, false},
606-
rspec.NetworkNamespace: {0, false},
607-
rspec.MountNamespace: {0, false},
608-
rspec.IPCNamespace: {0, false},
609-
rspec.UTSNamespace: {0, false},
610-
rspec.UserNamespace: {0, false},
611-
rspec.CgroupNamespace: {0, false},
612-
}
613-
614-
for index := 0; index < len(v.spec.Linux.Namespaces); index++ {
615-
ns := v.spec.Linux.Namespaces[index]
616-
if ns.Path != "" && !osFilepath.IsAbs(v.platform, ns.Path) {
617-
errs = multierror.Append(errs, specerror.NewError(specerror.NSPathAbs, fmt.Errorf("namespace.path %q is not an absolute path", ns.Path), rspec.Version))
618-
}
619-
620-
tmpItem := nsTypeList[ns.Type]
621-
tmpItem.num = tmpItem.num + 1
622-
if tmpItem.num > 1 {
623-
errs = multierror.Append(errs, specerror.NewError(specerror.NSErrorOnDup, fmt.Errorf("duplicated namespace %q", ns.Type), rspec.Version))
624-
}
625-
626-
if len(ns.Path) == 0 {
627-
tmpItem.newExist = true
628-
}
629-
nsTypeList[ns.Type] = tmpItem
630-
}
631-
632-
if (len(v.spec.Linux.UIDMappings) > 0 || len(v.spec.Linux.GIDMappings) > 0) && !nsTypeList[rspec.UserNamespace].newExist {
633-
errs = multierror.Append(errs, errors.New("the UID/GID mappings requires a new User namespace to be specified as well"))
634-
}
635-
636-
for k := range v.spec.Linux.Sysctl {
637-
if strings.HasPrefix(k, "net.") && !nsTypeList[rspec.NetworkNamespace].newExist {
638-
errs = multierror.Append(errs, fmt.Errorf("sysctl %v requires a new Network namespace to be specified as well", k))
639-
}
640-
if strings.HasPrefix(k, "fs.mqueue.") {
641-
if !nsTypeList[rspec.MountNamespace].newExist || !nsTypeList[rspec.IPCNamespace].newExist {
642-
errs = multierror.Append(errs, fmt.Errorf("sysctl %v requires a new IPC namespace and Mount namespace to be specified as well", k))
643-
}
644-
}
645-
}
646-
647-
if v.platform == "linux" && !nsTypeList[rspec.UTSNamespace].newExist && v.spec.Hostname != "" {
648-
errs = multierror.Append(errs, fmt.Errorf("on Linux, hostname requires a new UTS namespace to be specified as well"))
649-
}
650-
651-
// Linux devices validation
652-
devList := make(map[string]bool)
653-
devTypeList := make(map[string]bool)
654-
for index := 0; index < len(v.spec.Linux.Devices); index++ {
655-
device := v.spec.Linux.Devices[index]
656-
if !deviceValid(device) {
657-
errs = multierror.Append(errs, fmt.Errorf("device %v is invalid", device))
658-
}
659-
660-
if _, exists := devList[device.Path]; exists {
661-
errs = multierror.Append(errs, fmt.Errorf("device %s is duplicated", device.Path))
662-
} else {
663-
var rootfsPath string
664-
if filepath.IsAbs(v.spec.Root.Path) {
665-
rootfsPath = v.spec.Root.Path
666-
} else {
667-
rootfsPath = filepath.Join(v.bundlePath, v.spec.Root.Path)
668-
}
669-
absPath := filepath.Join(rootfsPath, device.Path)
670-
fi, err := os.Stat(absPath)
671-
if os.IsNotExist(err) {
672-
devList[device.Path] = true
673-
} else if err != nil {
674-
errs = multierror.Append(errs, err)
675-
} else {
676-
fStat, ok := fi.Sys().(*syscall.Stat_t)
677-
if !ok {
678-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesAvailable,
679-
fmt.Errorf("cannot determine state for device %s", device.Path), rspec.Version))
680-
continue
681-
}
682-
var devType string
683-
switch fStat.Mode & syscall.S_IFMT {
684-
case syscall.S_IFCHR:
685-
devType = "c"
686-
case syscall.S_IFBLK:
687-
devType = "b"
688-
case syscall.S_IFIFO:
689-
devType = "p"
690-
default:
691-
devType = "unmatched"
692-
}
693-
if devType != device.Type || (devType == "c" && device.Type == "u") {
694-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
695-
fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
696-
continue
697-
}
698-
if devType != "p" {
699-
dev := fStat.Rdev
700-
major := (dev >> 8) & 0xfff
701-
minor := (dev & 0xff) | ((dev >> 12) & 0xfff00)
702-
if int64(major) != device.Major || int64(minor) != device.Minor {
703-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
704-
fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
705-
continue
706-
}
707-
}
708-
if device.FileMode != nil {
709-
expectedPerm := *device.FileMode & os.ModePerm
710-
actualPerm := fi.Mode() & os.ModePerm
711-
if expectedPerm != actualPerm {
712-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
713-
fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
714-
continue
715-
}
716-
}
717-
if device.UID != nil {
718-
if *device.UID != fStat.Uid {
719-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
720-
fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
721-
continue
722-
}
723-
}
724-
if device.GID != nil {
725-
if *device.GID != fStat.Gid {
726-
errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch,
727-
fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version))
728-
continue
729-
}
730-
}
731-
}
732-
}
733-
734-
// unify u->c when comparing, they are synonyms
735-
var devID string
736-
if device.Type == "u" {
737-
devID = fmt.Sprintf("%s:%d:%d", "c", device.Major, device.Minor)
738-
} else {
739-
devID = fmt.Sprintf("%s:%d:%d", device.Type, device.Major, device.Minor)
740-
}
741-
742-
if _, exists := devTypeList[devID]; exists {
743-
logrus.Warnf("%v", specerror.NewError(specerror.DevicesErrorOnDup, fmt.Errorf("type:%s, major:%d and minor:%d for linux devices is duplicated", device.Type, device.Major, device.Minor), rspec.Version))
744-
} else {
745-
devTypeList[devID] = true
746-
}
747-
}
748-
749-
if v.spec.Linux.Resources != nil {
750-
errs = multierror.Append(errs, v.CheckLinuxResources())
751-
}
752-
753-
for _, maskedPath := range v.spec.Linux.MaskedPaths {
754-
if !strings.HasPrefix(maskedPath, "/") {
755-
errs = multierror.Append(errs,
756-
specerror.NewError(
757-
specerror.MaskedPathsAbs,
758-
fmt.Errorf("maskedPath %v is not an absolute path", maskedPath),
759-
rspec.Version))
760-
}
761-
}
762-
763-
for _, readonlyPath := range v.spec.Linux.ReadonlyPaths {
764-
if !strings.HasPrefix(readonlyPath, "/") {
765-
errs = multierror.Append(errs,
766-
specerror.NewError(
767-
specerror.ReadonlyPathsAbs,
768-
fmt.Errorf("readonlyPath %v is not an absolute path", readonlyPath),
769-
rspec.Version))
770-
}
771-
}
772-
773-
return
774-
}
775-
776592
// CheckLinuxResources checks v.spec.Linux.Resources
777593
func (v *Validator) CheckLinuxResources() (errs error) {
778594
logrus.Debugf("check linux resources")

0 commit comments

Comments
 (0)