From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id D5A5F138334 for ; Sun, 20 Jan 2019 04:51:38 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 417C2E09C6; Sun, 20 Jan 2019 04:51:37 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 17C92E09C6 for ; Sun, 20 Jan 2019 04:51:36 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2600:8802:604:6600:b06e:5315:d0a7:5889]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: zmedico) by smtp.gentoo.org (Postfix) with ESMTPSA id F11CE335C60; Sun, 20 Jan 2019 04:51:33 +0000 (UTC) From: Zac Medico To: gentoo-portage-dev@lists.gentoo.org Cc: Zac Medico Subject: [gentoo-portage-dev] [PATCH] pid-ns-init: fix child process signal disposition (bug 675828) Date: Sat, 19 Jan 2019 20:49:00 -0800 Message-Id: <20190120044900.5745-1-zmedico@gentoo.org> X-Mailer: git-send-email 2.18.1 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-portage-dev@lists.gentoo.org Reply-to: gentoo-portage-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: d685b077-861f-4e18-a7b4-dc81d0016771 X-Archives-Hash: 0a31ebd45b6817fa3d2066d7e5a71ae6 Use subprocess.Popen to correctly configure the signal disposition of the child process, since os.fork leaves the signal disposition in a state which may be inappropriate for various signals including SIGPIPE, SIGQUIT, SIGTERM, and SIGINT. For python implementations other that CPython >= 3, use preexec_fn to manually configure the signal disposition (I have found that this is necessary for CPython 2.7 and all PyPy versions tested, including PyPy3). Bug: https://bugs.gentoo.org/675828 Signed-off-by: Zac Medico --- bin/pid-ns-init | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/bin/pid-ns-init b/bin/pid-ns-init index 182d00a43..86029f983 100644 --- a/bin/pid-ns-init +++ b/bin/pid-ns-init @@ -2,18 +2,37 @@ # Copyright 2018-2019 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 +import errno import functools import os +import platform import signal +import subprocess import sys +if sys.version_info.major < 3 or platform.python_implementation() != 'CPython': + def signal_disposition_preexec(): + for signum in ( + signal.SIGHUP, + signal.SIGINT, + signal.SIGPIPE, + signal.SIGQUIT, + signal.SIGTERM, + ): + signal.signal(signum, signal.SIG_DFL) +else: + # CPython >= 3 subprocess.Popen handles this internally. + signal_disposition_preexec = None + + KILL_SIGNALS = ( signal.SIGINT, signal.SIGTERM, signal.SIGHUP, ) + def forward_kill_signal(main_child_pid, signum, frame): os.kill(main_child_pid, signum) @@ -28,14 +47,15 @@ def main(argv): # (forwarding signals to init and forwarding exit status to the parent # process). main_child_pid = int(argv[1]) + proc = None else: # The current process is init (pid 1) in a child pid namespace. binary = argv[1] args = argv[2:] - main_child_pid = os.fork() - if main_child_pid == 0: - os.execv(binary, args) + proc = subprocess.Popen(args, executable=binary, + preexec_fn=signal_disposition_preexec) + main_child_pid = proc.pid sig_handler = functools.partial(forward_kill_signal, main_child_pid) for signum in KILL_SIGNALS: @@ -50,6 +70,11 @@ def main(argv): continue raise if pid == main_child_pid: + if proc is not None: + # Suppress warning messages like this: + # ResourceWarning: subprocess 1234 is still running + proc.returncode = 0 + if os.WIFEXITED(status): return os.WEXITSTATUS(status) elif os.WIFSIGNALED(status): -- 2.18.1