diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go index 01809d0f2e6..e79b89eff73 100644 --- a/libcontainer/specconv/spec_linux.go +++ b/libcontainer/specconv/spec_linux.go @@ -238,24 +238,26 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) { config.Seccomp = seccomp } } - if spec.Process.SelinuxLabel != "" { - config.ProcessLabel = spec.Process.SelinuxLabel - } - if spec.Process != nil && spec.Process.OOMScoreAdj != nil { - config.OomScoreAdj = *spec.Process.OOMScoreAdj - } - if spec.Process.Capabilities != nil { - config.Capabilities = &configs.Capabilities{ - Bounding: spec.Process.Capabilities.Bounding, - Effective: spec.Process.Capabilities.Effective, - Permitted: spec.Process.Capabilities.Permitted, - Inheritable: spec.Process.Capabilities.Inheritable, - Ambient: spec.Process.Capabilities.Ambient, + if spec.Process != nil { + if spec.Process.SelinuxLabel != "" { + config.ProcessLabel = spec.Process.SelinuxLabel + } + if spec.Process.OOMScoreAdj != nil { + config.OomScoreAdj = *spec.Process.OOMScoreAdj + } + if spec.Process.Capabilities != nil { + config.Capabilities = &configs.Capabilities{ + Bounding: spec.Process.Capabilities.Bounding, + Effective: spec.Process.Capabilities.Effective, + Permitted: spec.Process.Capabilities.Permitted, + Inheritable: spec.Process.Capabilities.Inheritable, + Ambient: spec.Process.Capabilities.Ambient, + } } } createHooks(spec, config) config.Version = specs.Version - if spec.Linux.IntelRdt != nil { + if spec.Linux != nil && spec.Linux.IntelRdt != nil { config.IntelRdt = &configs.IntelRdt{} if spec.Linux.IntelRdt.L3CacheSchema != "" { config.IntelRdt.L3CacheSchema = spec.Linux.IntelRdt.L3CacheSchema diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 02ea753eda3..5b579235c25 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -3,6 +3,7 @@ package libcontainer import ( + "errors" "fmt" "os" "os/exec" @@ -152,12 +153,6 @@ func (l *linuxStandardInit) Init() error { if unix.Getppid() != l.parentPid { return unix.Kill(unix.Getpid(), unix.SIGKILL) } - // Check for the arg before waiting to make sure it exists and it is - // returned as a create time error. - name, err := exec.LookPath(l.config.Args[0]) - if err != nil { - return err - } // Close the pipe to signal that we have completed our init. l.pipe.Close() // Wait for the FIFO to be opened on the other side before exec-ing the @@ -186,6 +181,13 @@ func (l *linuxStandardInit) Init() error { return newSystemErrorWithCause(err, "init seccomp") } } + if len(l.config.Args) == 0 { + return errors.New("no process arguments configured") + } + name, err := exec.LookPath(l.config.Args[0]) + if err != nil { + return err + } if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { return newSystemErrorWithCause(err, "exec user process") } diff --git a/utils_linux.go b/utils_linux.go index 84731c844f0..99e72052f6e 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -97,7 +97,10 @@ func getDefaultImagePath(context *cli.Context) string { // newProcess returns a new libcontainer Process with the arguments from the // spec and stdio from the current process. -func newProcess(p specs.Process) (*libcontainer.Process, error) { +func newProcess(p *specs.Process) (*libcontainer.Process, error) { + if p == nil { + return &libcontainer.Process{}, nil + } lp := &libcontainer.Process{ Args: p.Args, Env: p.Env, @@ -261,7 +264,7 @@ func (r *runner) run(config *specs.Process) (int, error) { r.destroy() return -1, err } - process, err := newProcess(*config) + process, err := newProcess(config) if err != nil { r.destroy() return -1, err @@ -291,7 +294,8 @@ func (r *runner) run(config *specs.Process) (int, error) { // with detaching containers, and then we get a tty after the container has // started. handler := newSignalHandler(r.enableSubreaper, r.notifySocket) - tty, err := setupIO(process, rootuid, rootgid, config.Terminal, detach, r.consoleSocket) + terminal := config != nil && config.Terminal + tty, err := setupIO(process, rootuid, rootgid, terminal, detach, r.consoleSocket) if err != nil { r.destroy() return -1, err @@ -353,17 +357,21 @@ func (r *runner) terminate(p *libcontainer.Process) { func (r *runner) checkTerminal(config *specs.Process) error { detach := r.detach || (r.action == CT_ACT_CREATE) + terminal := config != nil && config.Terminal // Check command-line for sanity. - if detach && config.Terminal && r.consoleSocket == "" { + if detach && terminal && r.consoleSocket == "" { return fmt.Errorf("cannot allocate tty if runc will detach without setting console socket") } - if (!detach || !config.Terminal) && r.consoleSocket != "" { + if (!detach || !terminal) && r.consoleSocket != "" { return fmt.Errorf("cannot use console socket if runc will not detach or allocate tty") } return nil } func validateProcessSpec(spec *specs.Process) error { + if spec == nil { + return nil + } if spec.Cwd == "" { return fmt.Errorf("Cwd property must not be empty") }