From 178c70e6e0c4a7dda905afcb5a6d30e41ee62440 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 21 Mar 2022 13:30:05 -0400 Subject: [PATCH] MaybeReexecUsingUserNamespace: handle SIGHUP/SIGINT/SIGTERM Pass along SIGHUP, SIGINT, and SIGTERM if the parent receives them while the child process is running. Set SIGKILL as the child's parent-death signal so that, if we exit for some reason before the child does, it will be stopped. Signed-off-by: Nalin Dahyabhai --- pkg/unshare/unshare_linux.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/unshare/unshare_linux.go b/pkg/unshare/unshare_linux.go index 0d226e183c..c352efce0a 100644 --- a/pkg/unshare/unshare_linux.go +++ b/pkg/unshare/unshare_linux.go @@ -9,6 +9,7 @@ import ( "io" "os" "os/exec" + "os/signal" "os/user" "runtime" "strconv" @@ -484,6 +485,30 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) { // Finish up. logrus.Debugf("Running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings) + + // Forward SIGHUP, SIGINT, and SIGTERM to our child process. + interrupted := make(chan os.Signal, 100) + defer func() { + signal.Stop(interrupted) + close(interrupted) + }() + cmd.Hook = func(int) error { + go func() { + for receivedSignal := range interrupted { + cmd.Cmd.Process.Signal(receivedSignal) + } + }() + return nil + } + signal.Notify(interrupted, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) + + // Make sure our child process gets SIGKILLed if we exit, for whatever + // reason, before it does. + if cmd.Cmd.SysProcAttr == nil { + cmd.Cmd.SysProcAttr = &syscall.SysProcAttr{} + } + cmd.Cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL + ExecRunnable(cmd, nil) }