From: Zac Medico <zmedico@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: Arfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>,
Zac Medico <zmedico@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH] pid-sandbox: run pid-ns-init as root (bug 675868)
Date: Tue, 22 Jan 2019 00:30:34 -0800 [thread overview]
Message-ID: <20190122083034.2624-1-zmedico@gentoo.org> (raw)
From: Arfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>
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>
---
bin/pid-ns-init | 49 ++++++++++++++++++++++++++----------------
lib/portage/process.py | 12 +++++++++--
2 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index f9b8cc4f3..486fd13da 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,
@@ -37,9 +22,31 @@ def forward_kill_signal(main_child_pid, signum, frame):
os.kill(main_child_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
@@ -50,13 +57,17 @@ 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
- 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
sig_handler = functools.partial(forward_kill_signal, main_child_pid)
diff --git a/lib/portage/process.py b/lib/portage/process.py
index dd3d58ddc..0dba55de3 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -1,5 +1,5 @@
# portage.py -- core Portage functionality
-# Copyright 1998-2018 Gentoo Authors
+# Copyright 1998-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
@@ -467,7 +467,7 @@ def _exec(binary, mycommand, opt_name, fd_pipes,
@param gid: Group ID to run the process under
@type gid: Integer
@param groups: Groups the Process should be in.
- @type groups: Integer
+ @type groups: List
@param uid: User ID to run the process under
@type uid: Integer
@param umask: an int representing a unix umask (see man chmod for umask details)
@@ -571,8 +571,16 @@ def _exec(binary, mycommand, opt_name, fd_pipes,
portage._python_interpreter,
os.path.join(portage._bin_path,
'pid-ns-init'),
+ _unicode_encode('' if uid is None else str(uid)),
+ _unicode_encode('' if gid is None else str(gid)),
+ _unicode_encode('' if groups is None else ','.join(str(group) for group in groups)),
+ _unicode_encode('' if umask is None else str(umask)),
_unicode_encode(','.join(str(fd) for fd in fd_pipes)),
binary] + myargs
+ uid = None
+ gid = None
+ groups = None
+ umask = None
else:
# Execute a supervisor process which will forward
# signals to init and forward exit status to the
--
2.18.1
reply other threads:[~2019-01-22 8:32 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190122083034.2624-1-zmedico@gentoo.org \
--to=zmedico@gentoo.org \
--cc=Arfrever@Apache.Org \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox