mirror of
https://github.com/gravitational/teleport
synced 2024-10-21 09:44:51 +00:00
Set PDEATHSIG to SIGKILL on child processes after reexec
To execute an SSH command, Teleport re-executes itself and execs the command from this child process: teleport -> teleport exec -> sh -c "user command" Both parent teleport processes could exit unexpectedly (from SIGKILL or even connection interruption). Make sure all child processes get cleaned up and not orphaned to PID 1: - teleport exec via SIGQUIT to request graceful shutdown - user command via SIGKILL because it might ignore other signals
This commit is contained in:
parent
c6fe327938
commit
12952b4904
|
@ -26,6 +26,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -168,6 +169,7 @@ func (s *ExecSuite) TestOSCommandPrep(c *check.C) {
|
|||
c.Assert(cmd.Args, check.DeepEquals, []string{"-sh"})
|
||||
c.Assert(cmd.Dir, check.Equals, s.usr.HomeDir)
|
||||
c.Assert(cmd.Env, check.DeepEquals, expectedEnv)
|
||||
c.Assert(cmd.SysProcAttr.Pdeathsig, check.Equals, syscall.SIGKILL)
|
||||
|
||||
// Non-empty command (exec a prog).
|
||||
s.ctx.ExecRequest.SetCommand("ls -lh /etc")
|
||||
|
@ -180,6 +182,7 @@ func (s *ExecSuite) TestOSCommandPrep(c *check.C) {
|
|||
c.Assert(cmd.Args, check.DeepEquals, []string{"/bin/sh", "-c", "ls -lh /etc"})
|
||||
c.Assert(cmd.Dir, check.Equals, s.usr.HomeDir)
|
||||
c.Assert(cmd.Env, check.DeepEquals, expectedEnv)
|
||||
c.Assert(cmd.SysProcAttr.Pdeathsig, check.Equals, syscall.SIGKILL)
|
||||
|
||||
// Command without args.
|
||||
s.ctx.ExecRequest.SetCommand("top")
|
||||
|
@ -189,6 +192,7 @@ func (s *ExecSuite) TestOSCommandPrep(c *check.C) {
|
|||
c.Assert(err, check.IsNil)
|
||||
c.Assert(cmd.Path, check.Equals, "/bin/sh")
|
||||
c.Assert(cmd.Args, check.DeepEquals, []string{"/bin/sh", "-c", "top"})
|
||||
c.Assert(cmd.SysProcAttr.Pdeathsig, check.Equals, syscall.SIGKILL)
|
||||
}
|
||||
|
||||
func (s *ExecSuite) TestLoginDefsParser(c *check.C) {
|
||||
|
|
|
@ -461,6 +461,9 @@ func buildCommand(c *execCommand, tty *os.File, pty *os.File, pamEnvironment []s
|
|||
uid, gid, groups)
|
||||
}
|
||||
|
||||
// Perform OS-specific tweaks to the command.
|
||||
userCommandOSTweaks(&cmd)
|
||||
|
||||
return &cmd, nil
|
||||
}
|
||||
|
||||
|
@ -510,7 +513,7 @@ func ConfigureCommand(ctx *ServerContext) (*exec.Cmd, error) {
|
|||
args := []string{executable, subCommand}
|
||||
|
||||
// Build the "teleport exec" command.
|
||||
return &exec.Cmd{
|
||||
cmd := &exec.Cmd{
|
||||
Path: executable,
|
||||
Args: args,
|
||||
Dir: executableDir,
|
||||
|
@ -518,5 +521,10 @@ func ConfigureCommand(ctx *ServerContext) (*exec.Cmd, error) {
|
|||
ctx.cmdr,
|
||||
ctx.contr,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Perform OS-specific tweaks to the command.
|
||||
reexecCommandOSTweaks(cmd)
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
|
29
lib/srv/reexec_linux.go
Normal file
29
lib/srv/reexec_linux.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
// +build linux
|
||||
|
||||
package srv
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func reexecCommandOSTweaks(cmd *exec.Cmd) {
|
||||
if cmd.SysProcAttr == nil {
|
||||
cmd.SysProcAttr = new(syscall.SysProcAttr)
|
||||
}
|
||||
// Linux only: when parent process (node) dies unexpectedly without
|
||||
// cleaning up child processes, send a signal for graceful shutdown
|
||||
// to children.
|
||||
cmd.SysProcAttr.Pdeathsig = syscall.SIGQUIT
|
||||
}
|
||||
|
||||
func userCommandOSTweaks(cmd *exec.Cmd) {
|
||||
if cmd.SysProcAttr == nil {
|
||||
cmd.SysProcAttr = new(syscall.SysProcAttr)
|
||||
}
|
||||
// Linux only: when parent process (this process) dies unexpectedly, kill
|
||||
// the child process instead of orphaning it.
|
||||
// SIGKILL because we don't control the child process and it could choose
|
||||
// to ignore other signals.
|
||||
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL
|
||||
}
|
11
lib/srv/reexec_other.go
Normal file
11
lib/srv/reexec_other.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// +build !linux
|
||||
|
||||
package srv
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func reexecCommandOSTweaks(cmd *exec.Cmd) {}
|
||||
|
||||
func userCommandOSTweaks(cmd *exec.Cmd) {}
|
Loading…
Reference in a new issue