Merge pull request #980 from LK4D4/safer_hook_run

libcontainer/configs: make hooks run safer
This commit is contained in:
Aleksa Sarai 2016-08-09 22:22:04 +10:00 committed by GitHub
commit 0f76457138
1 changed files with 24 additions and 15 deletions

View File

@ -300,29 +300,38 @@ func (c Command) Run(s HookState) error {
if err != nil { if err != nil {
return err return err
} }
var stdout, stderr bytes.Buffer
cmd := exec.Cmd{ cmd := exec.Cmd{
Path: c.Path, Path: c.Path,
Args: c.Args, Args: c.Args,
Env: c.Env, Env: c.Env,
Stdin: bytes.NewReader(b), Stdin: bytes.NewReader(b),
Stdout: &stdout,
Stderr: &stderr,
}
if err := cmd.Start(); err != nil {
return err
} }
errC := make(chan error, 1) errC := make(chan error, 1)
go func() { go func() {
out, err := cmd.CombinedOutput() err := cmd.Wait()
if err != nil { if err != nil {
err = fmt.Errorf("%s: %s", err, out) err = fmt.Errorf("error running hook: %v, stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
} }
errC <- err errC <- err
}() }()
var timerCh <-chan time.Time
if c.Timeout != nil { if c.Timeout != nil {
select { timer := time.NewTimer(*c.Timeout)
case err := <-errC: defer timer.Stop()
return err timerCh = timer.C
case <-time.After(*c.Timeout): }
cmd.Process.Kill() select {
cmd.Wait() case err := <-errC:
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds()) return err
} case <-timerCh:
cmd.Process.Kill()
cmd.Wait()
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
} }
return <-errC
} }