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
-- 
2.13.6


Reply via email to