Merge pull request #2413 from JFHwang/2392-spec-check

Add nil check of spec.Process in validateProcessSpec()
This commit is contained in:
Akihiro Suda 2020-05-19 08:11:22 +09:00 committed by GitHub
commit f369199ff6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 94 additions and 82 deletions

View File

@ -3,6 +3,7 @@
package main
import (
"errors"
"fmt"
"os"
"strconv"
@ -91,11 +92,11 @@ func setPageServer(context *cli.Context, options *libcontainer.CriuOpts) {
if psOpt := context.String("page-server"); psOpt != "" {
addressPort := strings.Split(psOpt, ":")
if len(addressPort) != 2 {
fatal(fmt.Errorf("Use --page-server ADDRESS:PORT to specify page server"))
fatal(errors.New("Use --page-server ADDRESS:PORT to specify page server"))
}
portInt, err := strconv.Atoi(addressPort[1])
if err != nil {
fatal(fmt.Errorf("Invalid port number"))
fatal(errors.New("Invalid port number"))
}
options.PageServer = libcontainer.CriuPageServerInfo{
Address: addressPort[0],
@ -114,7 +115,7 @@ func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts)
case "strict":
options.ManageCgroupsMode = libcontainer.CRIU_CG_MODE_STRICT
default:
fatal(fmt.Errorf("Invalid manage cgroups mode"))
fatal(errors.New("Invalid manage cgroups mode"))
}
}
}

View File

@ -3,6 +3,7 @@
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
@ -23,7 +24,7 @@ func killContainer(container libcontainer.Container) error {
return nil
}
}
return fmt.Errorf("container init still running")
return errors.New("container init still running")
}
var deleteCommand = cli.Command{

View File

@ -4,6 +4,7 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"sync"
@ -40,7 +41,7 @@ information is displayed once every 5 seconds.`,
}
duration := context.Duration("interval")
if duration <= 0 {
return fmt.Errorf("duration interval must be greater than 0")
return errors.New("duration interval must be greater than 0")
}
status, err := container.Status()
if err != nil {

View File

@ -35,7 +35,7 @@ var (
HugePageSizes, _ = cgroups.GetHugePageSize()
)
var errSubsystemDoesNotExist = fmt.Errorf("cgroup: subsystem does not exist")
var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist")
type subsystemSet []subsystem
@ -308,7 +308,7 @@ func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
}
if (c.Name != "" || c.Parent != "") && c.Path != "" {
return nil, fmt.Errorf("cgroup: either Path or Name and Parent should be used")
return nil, errors.New("cgroup: either Path or Name and Parent should be used")
}
// XXX: Do not remove this code. Path safety is important! -- cyphar

View File

@ -4,7 +4,7 @@ package fs
import (
"bytes"
"fmt"
"errors"
"io/ioutil"
"os"
"path/filepath"
@ -131,7 +131,7 @@ func (s *CpusetGroup) ensureParent(current, root string) error {
}
// Avoid infinite recursion.
if parent == current {
return fmt.Errorf("cpuset: cgroup parent path outside cgroup root")
return errors.New("cpuset: cgroup parent path outside cgroup root")
}
if err := s.ensureParent(parent, root); err != nil {
return err

View File

@ -4,7 +4,7 @@ package fs
import (
"bytes"
"fmt"
"errors"
"reflect"
"github.com/opencontainers/runc/libcontainer/cgroups"
@ -95,9 +95,9 @@ func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
return err
}
if !target.IsBlacklist() && !reflect.DeepEqual(currentAfter, target) {
return fmt.Errorf("resulting devices cgroup doesn't precisely match target")
return errors.New("resulting devices cgroup doesn't precisely match target")
} else if target.IsBlacklist() != currentAfter.IsBlacklist() {
return fmt.Errorf("resulting devices cgroup doesn't match target mode")
return errors.New("resulting devices cgroup doesn't match target mode")
}
}
return nil

View File

@ -3,6 +3,7 @@
package fs
import (
"errors"
"fmt"
"reflect"
"testing"
@ -12,7 +13,7 @@ import (
func blkioStatEntryEquals(expected, actual []cgroups.BlkioStatEntry) error {
if len(expected) != len(actual) {
return fmt.Errorf("blkioStatEntries length do not match")
return errors.New("blkioStatEntries length do not match")
}
for i, expValue := range expected {
actValue := actual[i]

View File

@ -3,7 +3,7 @@
package systemd
import (
"fmt"
"errors"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
@ -19,23 +19,23 @@ func IsRunningSystemd() bool {
}
func NewSystemdCgroupsManager() (func(config *configs.Cgroup, paths map[string]string) cgroups.Manager, error) {
return nil, fmt.Errorf("Systemd not supported")
return nil, errors.New("Systemd not supported")
}
func (m *Manager) Apply(pid int) error {
return fmt.Errorf("Systemd not supported")
return errors.New("Systemd not supported")
}
func (m *Manager) GetPids() ([]int, error) {
return nil, fmt.Errorf("Systemd not supported")
return nil, errors.New("Systemd not supported")
}
func (m *Manager) GetAllPids() ([]int, error) {
return nil, fmt.Errorf("Systemd not supported")
return nil, errors.New("Systemd not supported")
}
func (m *Manager) Destroy() error {
return fmt.Errorf("Systemd not supported")
return errors.New("Systemd not supported")
}
func (m *Manager) GetPaths() map[string]string {
@ -47,21 +47,21 @@ func (m *Manager) Path(_ string) string {
}
func (m *Manager) GetStats() (*cgroups.Stats, error) {
return nil, fmt.Errorf("Systemd not supported")
return nil, errors.New("Systemd not supported")
}
func (m *Manager) Set(container *configs.Config) error {
return fmt.Errorf("Systemd not supported")
return errors.New("Systemd not supported")
}
func (m *Manager) Freeze(state configs.FreezerState) error {
return fmt.Errorf("Systemd not supported")
return errors.New("Systemd not supported")
}
func Freeze(c *configs.Cgroup, state configs.FreezerState) error {
return fmt.Errorf("Systemd not supported")
return errors.New("Systemd not supported")
}
func (m *Manager) GetCgroups() (*configs.Cgroup, error) {
return nil, fmt.Errorf("Systemd not supported")
return nil, errors.New("Systemd not supported")
}

View File

@ -1,6 +1,7 @@
package validate
import (
"errors"
"fmt"
"strings"
@ -35,14 +36,14 @@ func hasIDMapping(id int, mappings []configs.IDMap) bool {
func rootlessEUIDMappings(config *configs.Config) error {
if !config.Namespaces.Contains(configs.NEWUSER) {
return fmt.Errorf("rootless container requires user namespaces")
return errors.New("rootless container requires user namespaces")
}
if len(config.UidMappings) == 0 {
return fmt.Errorf("rootless containers requires at least one UID mapping")
return errors.New("rootless containers requires at least one UID mapping")
}
if len(config.GidMappings) == 0 {
return fmt.Errorf("rootless containers requires at least one GID mapping")
return errors.New("rootless containers requires at least one GID mapping")
}
return nil
}
@ -67,7 +68,7 @@ func rootlessEUIDMount(config *configs.Config) error {
continue
}
if !hasIDMapping(uid, config.UidMappings) {
return fmt.Errorf("cannot specify uid= mount options for unmapped uid in rootless containers")
return errors.New("cannot specify uid= mount options for unmapped uid in rootless containers")
}
}
@ -79,7 +80,7 @@ func rootlessEUIDMount(config *configs.Config) error {
continue
}
if !hasIDMapping(gid, config.GidMappings) {
return fmt.Errorf("cannot specify gid= mount options for unmapped gid in rootless containers")
return errors.New("cannot specify gid= mount options for unmapped gid in rootless containers")
}
}
}

View File

@ -1,6 +1,7 @@
package validate
import (
"errors"
"fmt"
"os"
"path/filepath"
@ -80,7 +81,7 @@ func (v *ConfigValidator) rootfs(config *configs.Config) error {
func (v *ConfigValidator) network(config *configs.Config) error {
if !config.Namespaces.Contains(configs.NEWNET) {
if len(config.Networks) > 0 || len(config.Routes) > 0 {
return fmt.Errorf("unable to apply network settings without a private NET namespace")
return errors.New("unable to apply network settings without a private NET namespace")
}
}
return nil
@ -88,7 +89,7 @@ func (v *ConfigValidator) network(config *configs.Config) error {
func (v *ConfigValidator) hostname(config *configs.Config) error {
if config.Hostname != "" && !config.Namespaces.Contains(configs.NEWUTS) {
return fmt.Errorf("unable to set hostname without a private UTS namespace")
return errors.New("unable to set hostname without a private UTS namespace")
}
return nil
}
@ -97,10 +98,10 @@ func (v *ConfigValidator) security(config *configs.Config) error {
// restrict sys without mount namespace
if (len(config.MaskPaths) > 0 || len(config.ReadonlyPaths) > 0) &&
!config.Namespaces.Contains(configs.NEWNS) {
return fmt.Errorf("unable to restrict sys entries without a private MNT namespace")
return errors.New("unable to restrict sys entries without a private MNT namespace")
}
if config.ProcessLabel != "" && !selinux.GetEnabled() {
return fmt.Errorf("selinux label is specified in config, but selinux is disabled or not supported")
return errors.New("selinux label is specified in config, but selinux is disabled or not supported")
}
return nil
@ -109,11 +110,11 @@ func (v *ConfigValidator) security(config *configs.Config) error {
func (v *ConfigValidator) usernamespace(config *configs.Config) error {
if config.Namespaces.Contains(configs.NEWUSER) {
if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) {
return fmt.Errorf("USER namespaces aren't enabled in the kernel")
return errors.New("USER namespaces aren't enabled in the kernel")
}
} else {
if config.UidMappings != nil || config.GidMappings != nil {
return fmt.Errorf("User namespace mappings specified, but USER namespace isn't enabled in the config")
return errors.New("User namespace mappings specified, but USER namespace isn't enabled in the config")
}
}
return nil
@ -122,7 +123,7 @@ func (v *ConfigValidator) usernamespace(config *configs.Config) error {
func (v *ConfigValidator) cgroupnamespace(config *configs.Config) error {
if config.Namespaces.Contains(configs.NEWCGROUP) {
if _, err := os.Stat("/proc/self/ns/cgroup"); os.IsNotExist(err) {
return fmt.Errorf("cgroup namespaces aren't enabled in the kernel")
return errors.New("cgroup namespaces aren't enabled in the kernel")
}
}
return nil
@ -182,21 +183,21 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
func (v *ConfigValidator) intelrdt(config *configs.Config) error {
if config.IntelRdt != nil {
if !intelrdt.IsCatEnabled() && !intelrdt.IsMbaEnabled() {
return fmt.Errorf("intelRdt is specified in config, but Intel RDT is not supported or enabled")
return errors.New("intelRdt is specified in config, but Intel RDT is not supported or enabled")
}
if !intelrdt.IsCatEnabled() && config.IntelRdt.L3CacheSchema != "" {
return fmt.Errorf("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled")
return errors.New("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled")
}
if !intelrdt.IsMbaEnabled() && config.IntelRdt.MemBwSchema != "" {
return fmt.Errorf("intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled")
return errors.New("intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled")
}
if intelrdt.IsCatEnabled() && config.IntelRdt.L3CacheSchema == "" {
return fmt.Errorf("Intel RDT/CAT is enabled and intelRdt is specified in config, but intelRdt.l3CacheSchema is empty")
return errors.New("Intel RDT/CAT is enabled and intelRdt is specified in config, but intelRdt.l3CacheSchema is empty")
}
if intelrdt.IsMbaEnabled() && config.IntelRdt.MemBwSchema == "" {
return fmt.Errorf("Intel RDT/MBA is enabled and intelRdt is specified in config, but intelRdt.memBwSchema is empty")
return errors.New("Intel RDT/MBA is enabled and intelRdt is specified in config, but intelRdt.memBwSchema is empty")
}
}

View File

@ -209,7 +209,7 @@ func (c *linuxContainer) Set(config configs.Config) error {
return err
}
if status == Stopped {
return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
return newGenericError(errors.New("container not running"), ContainerNotRunning)
}
if err := c.cgroupManager.Set(&config); err != nil {
// Set configs back
@ -295,7 +295,7 @@ func readFromExecFifo(execFifo io.Reader) error {
return err
}
if len(data) <= 0 {
return fmt.Errorf("cannot start an already running container")
return errors.New("cannot start an already running container")
}
return nil
}
@ -398,7 +398,7 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error {
}
return nil
}
return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
return newGenericError(errors.New("container not running"), ContainerNotRunning)
}
func (c *linuxContainer) createExecFifo() error {
@ -700,7 +700,7 @@ func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.
err := c.criuSwrk(nil, req, criuOpts, false, nil)
if err != nil {
logrus.Debugf("%s", err)
return fmt.Errorf("CRIU feature check failed")
return errors.New("CRIU feature check failed")
}
logrus.Debugf("Feature check says: %s", criuFeatures)
@ -727,7 +727,7 @@ func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.
}
if missingFeatures {
return fmt.Errorf("CRIU is missing features")
return errors.New("CRIU is missing features")
}
return nil
@ -924,7 +924,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
}
if criuOpts.ImagesDirectory == "" {
return fmt.Errorf("invalid directory to save checkpoint")
return errors.New("invalid directory to save checkpoint")
}
// Since a container can be C/R'ed multiple times,
@ -1268,7 +1268,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
}
defer workDir.Close()
if criuOpts.ImagesDirectory == "" {
return fmt.Errorf("invalid directory to restore checkpoint")
return errors.New("invalid directory to restore checkpoint")
}
imageDir, err := os.Open(criuOpts.ImagesDirectory)
if err != nil {
@ -1573,10 +1573,10 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
return err
}
if n == 0 {
return fmt.Errorf("unexpected EOF")
return errors.New("unexpected EOF")
}
if n == len(buf) {
return fmt.Errorf("buffer is too small")
return errors.New("buffer is too small")
}
resp := new(criurpc.CriuResp)

View File

@ -271,10 +271,10 @@ func setupUser(config *initConfig) error {
// Rather than just erroring out later in setuid(2) and setgid(2), check
// that the user is mapped here.
if _, err := config.Config.HostUID(execUser.Uid); err != nil {
return fmt.Errorf("cannot set uid to unmapped user in user namespace")
return errors.New("cannot set uid to unmapped user in user namespace")
}
if _, err := config.Config.HostGID(execUser.Gid); err != nil {
return fmt.Errorf("cannot set gid to unmapped user in user namespace")
return errors.New("cannot set gid to unmapped user in user namespace")
}
if config.RootlessEUID {
@ -283,7 +283,7 @@ func setupUser(config *initConfig) error {
// this check earlier, but if libcontainer.Process.User was typesafe
// this might work.
if len(addGroups) > 0 {
return fmt.Errorf("cannot set any additional groups in a rootless container")
return errors.New("cannot set any additional groups in a rootless container")
}
}

View File

@ -3,7 +3,6 @@
package keys
import (
"fmt"
"strconv"
"strings"
@ -33,7 +32,7 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
res := strings.Split(dest, ";")
if len(res) < 5 {
return fmt.Errorf("Destination buffer for key description is too small")
return errors.New("Destination buffer for key description is too small")
}
// parse permissions

View File

@ -5,7 +5,6 @@ package libcontainer
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"os/exec"
@ -131,7 +130,7 @@ func (p *setnsProcess) start() (err error) {
// This shouldn't happen.
panic("unexpected procHooks in setns")
default:
return newSystemError(fmt.Errorf("invalid JSON payload from child"))
return newSystemError(errors.New("invalid JSON payload from child"))
}
})
@ -428,7 +427,7 @@ func (p *initProcess) start() (retErr error) {
}
sentResume = true
default:
return newSystemError(fmt.Errorf("invalid JSON payload from child"))
return newSystemError(errors.New("invalid JSON payload from child"))
}
return nil
@ -438,7 +437,7 @@ func (p *initProcess) start() (retErr error) {
return newSystemErrorWithCause(ierr, "container init")
}
if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume {
return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process"))
return newSystemError(errors.New("could not synchronise after executing prestart hooks with container process"))
}
if err := unix.Shutdown(int(p.messageSockPair.parent.Fd()), unix.SHUT_WR); err != nil {
return newSystemErrorWithCause(err, "shutting down init pipe")

View File

@ -4,6 +4,7 @@ package seccomp
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
@ -34,12 +35,12 @@ const (
// of the init until they join the namespace
func InitSeccomp(config *configs.Seccomp) error {
if config == nil {
return fmt.Errorf("cannot initialize Seccomp - nil config passed")
return errors.New("cannot initialize Seccomp - nil config passed")
}
defaultAction, err := getAction(config.DefaultAction)
if err != nil {
return fmt.Errorf("error initializing seccomp - invalid default action")
return errors.New("error initializing seccomp - invalid default action")
}
filter, err := libseccomp.NewFilter(defaultAction)
@ -67,7 +68,7 @@ func InitSeccomp(config *configs.Seccomp) error {
// Add a rule for each syscall
for _, call := range config.Syscalls {
if call == nil {
return fmt.Errorf("encountered nil syscall while initializing Seccomp")
return errors.New("encountered nil syscall while initializing Seccomp")
}
if err = matchCall(filter, call); err != nil {
@ -116,7 +117,7 @@ func getAction(act configs.Action) (libseccomp.ScmpAction, error) {
case configs.Log:
return actLog, nil
default:
return libseccomp.ActInvalid, fmt.Errorf("invalid action, cannot use in rule")
return libseccomp.ActInvalid, errors.New("invalid action, cannot use in rule")
}
}
@ -138,7 +139,7 @@ func getOperator(op configs.Operator) (libseccomp.ScmpCompareOp, error) {
case configs.MaskEqualTo:
return libseccomp.CompareMaskedEqual, nil
default:
return libseccomp.CompareInvalid, fmt.Errorf("invalid operator, cannot use in rule")
return libseccomp.CompareInvalid, errors.New("invalid operator, cannot use in rule")
}
}
@ -147,7 +148,7 @@ func getCondition(arg *configs.Arg) (libseccomp.ScmpCondition, error) {
cond := libseccomp.ScmpCondition{}
if arg == nil {
return cond, fmt.Errorf("cannot convert nil to syscall condition")
return cond, errors.New("cannot convert nil to syscall condition")
}
op, err := getOperator(arg.Op)
@ -161,11 +162,11 @@ func getCondition(arg *configs.Arg) (libseccomp.ScmpCondition, error) {
// Add a rule to match a single syscall
func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error {
if call == nil || filter == nil {
return fmt.Errorf("cannot use nil as syscall to block")
return errors.New("cannot use nil as syscall to block")
}
if len(call.Name) == 0 {
return fmt.Errorf("empty string is not a valid syscall")
return errors.New("empty string is not a valid syscall")
}
// If we can't resolve the syscall, assume it's not supported on this kernel

View File

@ -2,6 +2,7 @@ package libcontainer
import (
"encoding/json"
"errors"
"fmt"
"io"
@ -45,7 +46,7 @@ func readSync(pipe io.Reader, expected syncType) error {
var procSync syncT
if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
if err == io.EOF {
return fmt.Errorf("parent closed synchronisation channel")
return errors.New("parent closed synchronisation channel")
}
return fmt.Errorf("failed reading error from parent: %v", err)
}
@ -61,7 +62,7 @@ func readSync(pipe io.Reader, expected syncType) error {
}
if procSync.Type != expected {
return fmt.Errorf("invalid synchronisation flag from parent")
return errors.New("invalid synchronisation flag from parent")
}
return nil
}

View File

@ -3,6 +3,7 @@
package main
import (
"errors"
"fmt"
"io/ioutil"
"os"
@ -107,7 +108,7 @@ To list containers created using a non-default value for "--root":
return err
}
default:
return fmt.Errorf("invalid format option")
return errors.New("invalid format option")
}
return nil
},

5
ps.go
View File

@ -4,6 +4,7 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
@ -52,7 +53,7 @@ var psCommand = cli.Command{
case "json":
return json.NewEncoder(os.Stdout).Encode(pids)
default:
return fmt.Errorf("invalid format option")
return errors.New("invalid format option")
}
// [1:] is to remove command name, ex:
@ -109,5 +110,5 @@ func getPidIndex(title string) (int, error) {
}
}
return pidIndex, fmt.Errorf("couldn't find PID field in ps output")
return pidIndex, errors.New("couldn't find PID field in ps output")
}

View File

@ -4,6 +4,7 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
@ -274,11 +275,11 @@ other options are ignored.
l3CacheSchema := context.String("l3-cache-schema")
memBwSchema := context.String("mem-bw-schema")
if l3CacheSchema != "" && !intelrdt.IsCatEnabled() {
return fmt.Errorf("Intel RDT/CAT: l3 cache schema is not enabled")
return errors.New("Intel RDT/CAT: l3 cache schema is not enabled")
}
if memBwSchema != "" && !intelrdt.IsMbaEnabled() {
return fmt.Errorf("Intel RDT/MBA: memory bandwidth schema is not enabled")
return errors.New("Intel RDT/MBA: memory bandwidth schema is not enabled")
}
if l3CacheSchema != "" || memBwSchema != "" {

View File

@ -53,7 +53,7 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
cgroupManager = libcontainer.RootlessSystemdCgroups
}
} else {
return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available")
return nil, errors.New("systemd cgroup flag passed, but systemd support for managing cgroups is not available")
}
}
@ -179,7 +179,7 @@ func setupIO(process *libcontainer.Process, rootuid, rootgid int, createTTY, det
}
uc, ok := conn.(*net.UnixConn)
if !ok {
return nil, fmt.Errorf("casting to UnixConn failed")
return nil, errors.New("casting to UnixConn failed")
}
t.postStart = append(t.postStart, uc)
socket, err := uc.File()
@ -369,26 +369,29 @@ func (r *runner) checkTerminal(config *specs.Process) error {
detach := r.detach || (r.action == CT_ACT_CREATE)
// Check command-line for sanity.
if detach && config.Terminal && r.consoleSocket == "" {
return fmt.Errorf("cannot allocate tty if runc will detach without setting console socket")
return errors.New("cannot allocate tty if runc will detach without setting console socket")
}
if (!detach || !config.Terminal) && r.consoleSocket != "" {
return fmt.Errorf("cannot use console socket if runc will not detach or allocate tty")
return errors.New("cannot use console socket if runc will not detach or allocate tty")
}
return nil
}
func validateProcessSpec(spec *specs.Process) error {
if spec == nil {
return errors.New("process property must not be empty")
}
if spec.Cwd == "" {
return fmt.Errorf("Cwd property must not be empty")
return errors.New("Cwd property must not be empty")
}
if !filepath.IsAbs(spec.Cwd) {
return fmt.Errorf("Cwd must be an absolute path")
return errors.New("Cwd must be an absolute path")
}
if len(spec.Args) == 0 {
return fmt.Errorf("args must not be empty")
return errors.New("args must not be empty")
}
if spec.SelinuxLabel != "" && !selinux.GetEnabled() {
return fmt.Errorf("selinux label is specified in config, but selinux is disabled or not supported")
return errors.New("selinux label is specified in config, but selinux is disabled or not supported")
}
return nil
}