summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2011-11-25 20:28:15 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2011-11-25 20:28:15 (GMT)
commit4558bad7d64a7599b46fb56ea2df52319437f3a0 (patch)
tree8cb5015f604888d24cf9cc88f0b3b66609f7ea27
parentfd9ebd4a361805607baea3e038652f207575ced8 (diff)
downloadcpython-4558bad7d64a7599b46fb56ea2df52319437f3a0.zip
cpython-4558bad7d64a7599b46fb56ea2df52319437f3a0.tar.gz
cpython-4558bad7d64a7599b46fb56ea2df52319437f3a0.tar.bz2
Issue #12856: Ensure child processes do not inherit the parent's random seed for filename generation in the tempfile module.
Patch by Brian Harring.
-rw-r--r--Lib/tempfile.py9
-rw-r--r--Lib/test/test_tempfile.py32
-rw-r--r--Misc/NEWS4
3 files changed, 43 insertions, 2 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 48b77a8..34dff30 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -112,8 +112,13 @@ class _RandomNameSequence:
characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
- def __init__(self):
- self.rng = _Random()
+ @property
+ def rng(self):
+ cur_pid = _os.getpid()
+ if cur_pid != getattr(self, '_rng_pid', None):
+ self._rng = _Random()
+ self._rng_pid = cur_pid
+ return self._rng
def __iter__(self):
return self
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index f7f5bda..50cf3b4 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -1,6 +1,7 @@
# tempfile.py unit tests.
import tempfile
import os
+import signal
import sys
import re
import warnings
@@ -135,6 +136,37 @@ class test__RandomNameSequence(TC):
except:
self.failOnException("iteration")
+ @unittest.skipUnless(hasattr(os, 'fork'),
+ "os.fork is required for this test")
+ def test_process_awareness(self):
+ # ensure that the random source differs between
+ # child and parent.
+ read_fd, write_fd = os.pipe()
+ pid = None
+ try:
+ pid = os.fork()
+ if not pid:
+ os.close(read_fd)
+ os.write(write_fd, next(self.r).encode("ascii"))
+ os.close(write_fd)
+ # bypass the normal exit handlers- leave those to
+ # the parent.
+ os._exit(0)
+ parent_value = next(self.r)
+ child_value = os.read(read_fd, len(parent_value)).decode("ascii")
+ finally:
+ if pid:
+ # best effort to ensure the process can't bleed out
+ # via any bugs above
+ try:
+ os.kill(pid, signal.SIGKILL)
+ except EnvironmentError:
+ pass
+ os.close(read_fd)
+ os.close(write_fd)
+ self.assertNotEqual(child_value, parent_value)
+
+
test_classes.append(test__RandomNameSequence)
diff --git a/Misc/NEWS b/Misc/NEWS
index f65fafe..fba2c3d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -83,6 +83,10 @@ Core and Builtins
Library
-------
+- Issue #12856: Ensure child processes do not inherit the parent's random
+ seed for filename generation in the tempfile module. Patch by Brian
+ Harring.
+
- Issue #13458: Fix a memory leak in the ssl module when decoding a
certificate with a subjectAltName. Patch by Robert Xiao.