aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>2019-01-21 17:14:03 +0100
committerZac Medico <zmedico@gentoo.org>2019-01-22 20:47:29 -0800
commit82e86efb503a23588b6b8e4351427cc3fca27de3 (patch)
tree93f7dd4254c6b7c28b275dd077b43e8a32ff37a7 /bin/pid-ns-init
parentpid-sandbox: pid-ns-init setsid support (bug 675870) (diff)
downloadportage-82e86efb503a23588b6b8e4351427cc3fca27de3.tar.gz
portage-82e86efb503a23588b6b8e4351427cc3fca27de3.tar.bz2
portage-82e86efb503a23588b6b8e4351427cc3fca27de3.zip
pid-sandbox: run pid-ns-init as root (bug 675868)
Drop permissions only for subprocess of pid-ns-init but not pid-ns-init itself. With FEATURES="pid-sandbox userpriv", pid-ns-init should be run with unchanged permissions (usually UID=0, GID=0). Bug: https://bugs.gentoo.org/675868 Signed-off-by: Arfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org> Signed-off-by: Zac Medico <zmedico@gentoo.org>
Diffstat (limited to 'bin/pid-ns-init')
-rw-r--r--bin/pid-ns-init49
1 files changed, 30 insertions, 19 deletions
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index 76ae8de75..f01d69fc2 100644
--- a/bin/pid-ns-init
+++ b/bin/pid-ns-init
@@ -11,21 +11,6 @@ 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,
@@ -41,9 +26,31 @@ def forward_kill_signal(pid, signum, frame):
os.kill(pid, signum)
+def preexec_fn(uid, gid, groups, umask):
+ if gid is not None:
+ os.setgid(gid)
+ if groups is not None:
+ os.setgroups(groups)
+ if uid is not None:
+ os.setuid(uid)
+ if umask is not None:
+ os.umask(umask)
+
+ # CPython >= 3 subprocess.Popen handles this internally.
+ if sys.version_info.major < 3 or platform.python_implementation() != 'CPython':
+ for signum in (
+ signal.SIGHUP,
+ signal.SIGINT,
+ signal.SIGPIPE,
+ signal.SIGQUIT,
+ signal.SIGTERM,
+ ):
+ signal.signal(signum, signal.SIG_DFL)
+
+
def main(argv):
if len(argv) < 2:
- return 'Usage: {} <main-child-pid> or <pass_fds> <binary> <argv0> [arg]..'.format(argv[0])
+ return 'Usage: {} <main-child-pid> or <uid> <gid> <groups> <umask> <pass_fds> <binary> <argv0> [arg]..'.format(argv[0])
if len(argv) == 2:
# The child process is init (pid 1) in a child pid namespace, and
@@ -55,16 +62,20 @@ def main(argv):
proc = None
else:
# The current process is init (pid 1) in a child pid namespace.
- pass_fds, binary, args = tuple(int(fd) for fd in argv[1].split(',')), argv[2], argv[3:]
+ uid, gid, groups, umask, pass_fds, binary, args = argv[1], argv[2], argv[3], argv[4], tuple(int(fd) for fd in argv[5].split(',')), argv[6], argv[7:]
+ uid = int(uid) if uid else None
+ gid = int(gid) if gid else None
+ groups = tuple(int(group) for group in groups.split(',')) if groups else None
+ umask = int(umask) if umask else None
popen_kwargs = {}
+ popen_kwargs['preexec_fn'] = functools.partial(preexec_fn, uid, gid, groups, umask)
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)
+ proc = subprocess.Popen(args, executable=binary, **popen_kwargs)
main_child_pid = proc.pid
# If setsid has been called, use kill(0, signum) to