aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2019-01-21 23:17:18 -0800
committerZac Medico <zmedico@gentoo.org>2019-01-22 20:47:25 -0800
commit37e4dc5ae842afa03849a47b123345906fdd81a2 (patch)
tree761c4296f7e545af95493f187854c421f0275701
parentinherit: use local -x ECLASS (bug 676014) (diff)
downloadportage-37e4dc5ae842afa03849a47b123345906fdd81a2.tar.gz
portage-37e4dc5ae842afa03849a47b123345906fdd81a2.tar.bz2
portage-37e4dc5ae842afa03849a47b123345906fdd81a2.zip
pid-sandbox: pid-ns-init setsid support (bug 675870)
Use setsid to isolate the parent process from signals sent to the process group, and forward signals to the entire process group with kill(0, signum). Bug: https://bugs.gentoo.org/675870 Signed-off-by: Zac Medico <zmedico@gentoo.org>
-rw-r--r--bin/pid-ns-init16
1 files changed, 13 insertions, 3 deletions
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index f9b8cc4f3..76ae8de75 100644
--- a/bin/pid-ns-init
+++ b/bin/pid-ns-init
@@ -33,8 +33,12 @@ KILL_SIGNALS = (
)
-def forward_kill_signal(main_child_pid, signum, frame):
- os.kill(main_child_pid, signum)
+def forward_kill_signal(pid, signum, frame):
+ if pid == 0:
+ # Avoid a signal feedback loop, since signals sent to the
+ # process group are also sent to the current process.
+ signal.signal(signum, signal.SIG_DFL)
+ os.kill(pid, signum)
def main(argv):
@@ -47,6 +51,7 @@ def main(argv):
# (forwarding signals to init and forwarding exit status to the parent
# process).
main_child_pid = int(argv[1])
+ setsid = False
proc = None
else:
# The current process is init (pid 1) in a child pid namespace.
@@ -55,11 +60,16 @@ def main(argv):
popen_kwargs = {}
if sys.version_info.major > 2:
popen_kwargs['pass_fds'] = pass_fds
+ # Isolate parent process from process group SIGSTOP (bug 675870)
+ setsid = True
+ os.setsid()
proc = subprocess.Popen(args, executable=binary,
preexec_fn=signal_disposition_preexec, **popen_kwargs)
main_child_pid = proc.pid
- sig_handler = functools.partial(forward_kill_signal, main_child_pid)
+ # If setsid has been called, use kill(0, signum) to
+ # forward signals to the entire process group.
+ sig_handler = functools.partial(forward_kill_signal, 0 if setsid else main_child_pid)
for signum in KILL_SIGNALS:
signal.signal(signum, sig_handler)