commit:     c01fdd27473a76d1c8b6edb1b9dfb2c29645b1c2
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 22 02:44:06 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Thu Feb 22 17:30:27 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=c01fdd27

emerge/ebuild: sanitize file descriptors on startup

In order to ensure that any unintentionally inherited file descriptors
will not be inherited by child processes, set the inheritable flag to
False on startup, except for those corresponding to stdin, stdout, and
stderr. This mitigates potential problems that might result from
making the portage.process.spawn close_fds parameter default to False
for versions of python with PEP 446 support.

Bug: https://bugs.gentoo.org/648432

 bin/ebuild             |  2 ++
 bin/emerge             |  1 +
 pym/portage/process.py | 24 ++++++++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/bin/ebuild b/bin/ebuild
index bda746f78..b1ef0573b 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -58,6 +58,8 @@ import portage.util
 from _emerge.Package import Package
 from _emerge.RootConfig import RootConfig
 
+portage.process.sanitize_fds()
+
 description = "See the ebuild(1) man page for more info"
 usage = "Usage: ebuild <ebuild file> <command> [command] ..."
 parser = argparse.ArgumentParser(description=description, usage=usage)

diff --git a/bin/emerge b/bin/emerge
index 43cfdcddb..5f08861e5 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -46,6 +46,7 @@ try:
        if __name__ == "__main__":
                from portage.exception import IsADirectory, ParseError, \
                                PermissionDenied
+               portage.process.sanitize_fds()
                try:
                        retval = emerge_main()
                except PermissionDenied as e:

diff --git a/pym/portage/process.py b/pym/portage/process.py
index 4d96f156e..2af783e22 100644
--- a/pym/portage/process.py
+++ b/pym/portage/process.py
@@ -91,6 +91,30 @@ sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and
 fakeroot_capable = (os.path.isfile(FAKEROOT_BINARY) and
                     os.access(FAKEROOT_BINARY, os.X_OK))
 
+
+def sanitize_fds():
+       """
+       Set the inheritable flag to False for all open file descriptors,
+       except for those corresponding to stdin, stdout, and stderr. This
+       ensures that any unintentionally inherited file descriptors will
+       not be inherited by child processes.
+       """
+       if _set_inheritable is not None:
+
+               whitelist = frozenset([
+                       sys.__stdin__.fileno(),
+                       sys.__stdout__.fileno(),
+                       sys.__stderr__.fileno(),
+               ])
+
+               for fd in get_open_fds():
+                       if fd not in whitelist:
+                               try:
+                                       _set_inheritable(fd, False)
+                               except OSError:
+                                       pass
+
+
 def spawn_bash(mycommand, debug=False, opt_name=None, **keywords):
        """
        Spawns a bash shell running a specific commands

Reply via email to