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
