summaryrefslogtreecommitdiffstats
path: root/Lib/multiprocessing/spawn.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-06-27 09:40:24 (GMT)
committerGitHub <noreply@github.com>2018-06-27 09:40:24 (GMT)
commit2cc9d21fffb8146d30e6fb4221e32410ba4b4ab7 (patch)
treea64c215f6670bd22695f9d1855956aa3d57a87e1 /Lib/multiprocessing/spawn.py
parentf15f66d275d1166839312c9ff3a67c00b486c7d6 (diff)
downloadcpython-2cc9d21fffb8146d30e6fb4221e32410ba4b4ab7.zip
cpython-2cc9d21fffb8146d30e6fb4221e32410ba4b4ab7.tar.gz
cpython-2cc9d21fffb8146d30e6fb4221e32410ba4b4ab7.tar.bz2
bpo-33929: multiprocessing: fix handle leak on race condition (GH-7921)
Fix a race condition in Popen of multiprocessing.popen_spawn_win32. The child process now duplicates the read end of pipe instead of "stealing" it. Previously, the read end of pipe was "stolen" by the child process, but it leaked a handle if the child process had been terminated before it could steal the handle from the parent process.
Diffstat (limited to 'Lib/multiprocessing/spawn.py')
-rw-r--r--Lib/multiprocessing/spawn.py10
1 files changed, 9 insertions, 1 deletions
diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py
index 1f4f3f4..2de4cb7 100644
--- a/Lib/multiprocessing/spawn.py
+++ b/Lib/multiprocessing/spawn.py
@@ -96,7 +96,15 @@ def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None):
assert is_forking(sys.argv), "Not forking"
if sys.platform == 'win32':
import msvcrt
- new_handle = reduction.steal_handle(parent_pid, pipe_handle)
+ import _winapi
+
+ if parent_pid is not None:
+ source_process = _winapi.OpenProcess(
+ _winapi.PROCESS_DUP_HANDLE, False, parent_pid)
+ else:
+ source_process = None
+ new_handle = reduction.duplicate(pipe_handle,
+ source_process=source_process)
fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY)
else:
from . import semaphore_tracker