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