1f22b15030
On Linux, when (os/exec.Cmd).SysProcAttr.Pdeathsig is set, the signal will be sent to the process when the OS thread on which cmd.Start() was executed dies. The runtime terminates an OS thread when a goroutine exits after being wired to the thread with runtime.LockOSThread(). If other goroutines are allowed to be scheduled onto a thread which called cmd.Start(), an unrelated goroutine could cause the thread to be terminated and prematurely signal the command. See https://github.com/golang/go/issues/27505 for more information. Prevent started subprocesses with Pdeathsig from getting signaled prematurely by wiring the starting goroutine to the OS thread until the subprocess has exited. No other goroutines can be scheduled onto a locked thread so it will remain alive until unlocked or the daemon process exits. Signed-off-by: Cory Snider <csnider@mirantis.com>
33 lines
980 B
Go
33 lines
980 B
Go
package reexec // import "github.com/docker/docker/pkg/reexec"
|
|
|
|
import (
|
|
"os/exec"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// Self returns the path to the current process's binary.
|
|
// Returns "/proc/self/exe".
|
|
func Self() string {
|
|
return "/proc/self/exe"
|
|
}
|
|
|
|
// Command returns *exec.Cmd which has Path as current binary. Also it setting
|
|
// SysProcAttr.Pdeathsig to SIGTERM.
|
|
// This will use the in-memory version (/proc/self/exe) of the current binary,
|
|
// it is thus safe to delete or replace the on-disk binary (os.Args[0]).
|
|
//
|
|
// As SysProcAttr.Pdeathsig is set, the signal will be sent to the process when
|
|
// the OS thread which created the process dies. It is the caller's
|
|
// responsibility to ensure that the creating thread is not terminated
|
|
// prematurely. See https://go.dev/issue/27505 for more details.
|
|
func Command(args ...string) *exec.Cmd {
|
|
return &exec.Cmd{
|
|
Path: Self(),
|
|
Args: args,
|
|
SysProcAttr: &syscall.SysProcAttr{
|
|
Pdeathsig: unix.SIGTERM,
|
|
},
|
|
}
|
|
}
|