Commit 4ccaf93b authored by Facundo Batista's avatar Facundo Batista

Issue #6274. Fixed a potential FD leak in subprocess.py.

parent 2cf40b1c
......@@ -1034,6 +1034,8 @@ class Popen(object):
# The first char specifies the exception type: 0 means
# OSError, 1 means some other error.
errpipe_read, errpipe_write = os.pipe()
try:
try:
self._set_cloexec_flag(errpipe_write)
gc_was_enabled = gc.isenabled()
......@@ -1067,11 +1069,12 @@ class Popen(object):
if errwrite is not None:
os.dup2(errwrite, 2)
# Close pipe fds. Make sure we don't close the same
# fd more than once, or standard fds.
# Close pipe fds. Make sure we don't close the
# same fd more than once, or standard fds.
if p2cread is not None and p2cread not in (0,):
os.close(p2cread)
if c2pwrite is not None and c2pwrite not in (p2cread, 1):
if c2pwrite is not None and \
c2pwrite not in (p2cread, 1):
os.close(c2pwrite)
if (errwrite is not None and
errwrite not in (p2cread, c2pwrite, 2)):
......@@ -1094,21 +1097,25 @@ class Popen(object):
except:
exc_type, exc_value, tb = sys.exc_info()
# Save the traceback and attach it to the exception object
# Save the traceback and attach it to the exception
# object
exc_lines = traceback.format_exception(exc_type,
exc_value,
tb)
exc_value.child_traceback = ''.join(exc_lines)
os.write(errpipe_write, pickle.dumps(exc_value))
# This exitcode won't be reported to applications, so it
# really doesn't matter what we return.
# This exitcode won't be reported to applications, so
# it really doesn't matter what we return.
os._exit(255)
# Parent
if gc_was_enabled:
gc.enable()
finally:
# be sure the FD is closed no matter what
os.close(errpipe_write)
if p2cread is not None and p2cwrite is not None:
os.close(p2cread)
if c2pwrite is not None and c2pread is not None:
......@@ -1116,9 +1123,13 @@ class Popen(object):
if errwrite is not None and errread is not None:
os.close(errwrite)
# Wait for exec to fail or succeed; possibly raising exception
data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
# Wait for exec to fail or succeed; possibly raising an
# exception (limited to 1 MB)
data = os.read(errpipe_read, 1048576)
finally:
# be sure the FD is closed no matter what
os.close(errpipe_read)
if data:
os.waitpid(self.pid, 0)
child_exception = pickle.loads(data)
......
......@@ -15,6 +15,8 @@ Core and Builtins
Library
-------
- Issue #6274: Fixed possible file descriptors leak in subprocess.py
- Accessing io.StringIO.buffer now raises an AttributeError instead of
io.UnsupportedOperation.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment