diff --git a/client/driver/executor/executor.go b/client/driver/executor/executor.go index 8644b5aa049..1bb028213f3 100644 --- a/client/driver/executor/executor.go +++ b/client/driver/executor/executor.go @@ -176,11 +176,12 @@ type UniversalExecutor struct { ctx *ExecutorContext command *ExecCommand - pids map[int]*nomadPid - pidLock sync.RWMutex - taskDir string - exitState *ProcessState - processExited chan interface{} + pids map[int]*nomadPid + pidLock sync.RWMutex + taskDir string + exitState *ProcessState + processExited chan interface{} + fsIsolationEnforced bool lre *logging.FileRotator lro *logging.FileRotator @@ -230,23 +231,30 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand, ctx *ExecutorContext e.ctx = ctx e.command = command + // setting the user of the process + if command.User != "" { + e.logger.Printf("[DEBUG] executor: running command as %s", command.User) + if err := e.runAs(command.User); err != nil { + return nil, err + } + } + // configuring the task dir if err := e.configureTaskDir(); err != nil { return nil, err } + e.ctx.TaskEnv.Build() // configuring the chroot, cgroup and enters the plugin process in the // chroot if err := e.configureIsolation(); err != nil { return nil, err } - - // setting the user of the process - if command.User != "" { - e.logger.Printf("[DEBUG] executor: running command as %s", command.User) - if err := e.runAs(command.User); err != nil { - return nil, err - } + // Apply ourselves into the cgroup. The executor MUST be in the cgroup + // before the user task is started, otherwise we are subject to a fork + // attack in which a process escapes isolation by immediately forking. + if err := e.applyLimits(os.Getpid()); err != nil { + return nil, err } // Setup the loggers @@ -256,8 +264,6 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand, ctx *ExecutorContext e.cmd.Stdout = e.lro e.cmd.Stderr = e.lre - e.ctx.TaskEnv.Build() - // Look up the binary path and make it executable absPath, err := e.lookupBin(ctx.TaskEnv.ReplaceEnv(command.Cmd)) if err != nil { @@ -268,10 +274,11 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand, ctx *ExecutorContext return nil, err } - // Determine the path to run as it may have to be relative to the chroot. path := absPath - if e.command.FSIsolation { - rel, err := filepath.Rel(e.taskDir, absPath) + + // Determine the path to run as it may have to be relative to the chroot. + if e.fsIsolationEnforced { + rel, err := filepath.Rel(e.taskDir, path) if err != nil { return nil, err } @@ -280,16 +287,9 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand, ctx *ExecutorContext // Set the commands arguments e.cmd.Path = path - e.cmd.Args = append([]string{path}, ctx.TaskEnv.ParseAndReplace(command.Args)...) + e.cmd.Args = append([]string{e.cmd.Path}, ctx.TaskEnv.ParseAndReplace(command.Args)...) e.cmd.Env = ctx.TaskEnv.EnvList() - // Apply ourselves into the cgroup. The executor MUST be in the cgroup - // before the user task is started, otherwise we are subject to a fork - // attack in which a process escapes isolation by immediately forking. - if err := e.applyLimits(os.Getpid()); err != nil { - return nil, err - } - // Start the process if err := e.cmd.Start(); err != nil { return nil, err diff --git a/client/driver/executor/executor_linux.go b/client/driver/executor/executor_linux.go index 812d1a0017e..1140e3005c7 100644 --- a/client/driver/executor/executor_linux.go +++ b/client/driver/executor/executor_linux.go @@ -247,6 +247,7 @@ func (e *UniversalExecutor) configureChroot() error { return err } + e.fsIsolationEnforced = true return nil } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index ba476fe9775..1f71ad0fc24 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -1849,13 +1849,6 @@ func (t *Task) Validate() error { } } - // If the driver is java or qemu ensure that they have specified an - // artifact. - if (t.Driver == "qemu" || t.Driver == "java") && len(t.Artifacts) == 0 { - err := fmt.Errorf("must specify at least one artifact when using %q driver", t.Driver) - mErr.Errors = append(mErr.Errors, err) - } - return mErr.ErrorOrNil() }