diff options
author | Zac Medico <zmedico@gentoo.org> | 2019-01-21 23:17:18 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2019-01-22 20:47:25 -0800 |
commit | 37e4dc5ae842afa03849a47b123345906fdd81a2 (patch) | |
tree | 761c4296f7e545af95493f187854c421f0275701 /bin | |
parent | inherit: use local -x ECLASS (bug 676014) (diff) | |
download | portage-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>
Diffstat (limited to 'bin')
-rw-r--r-- | bin/pid-ns-init | 16 |
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) |