[Python-checkins] cpython (2.7): Issue #12856: Ensure child processes do not inherit the parent's random seed

antoine.pitrou python-checkins at python.org
Fri Nov 25 21:38:20 CET 2011


http://hg.python.org/cpython/rev/e42be90eb9c5
changeset:   73745:e42be90eb9c5
branch:      2.7
parent:      73725:d1bdafa161e7
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Fri Nov 25 21:28:15 2011 +0100
summary:
  Issue #12856: Ensure child processes do not inherit the parent's random seed for filename generation in the tempfile module.
Patch by Brian Harring.

files:
  Lib/tempfile.py           |   9 ++++++-
  Lib/test/test_tempfile.py |  32 +++++++++++++++++++++++++++
  Misc/NEWS                 |   4 +++
  3 files changed, 44 insertions(+), 1 deletions(-)


diff --git a/Lib/tempfile.py b/Lib/tempfile.py
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -118,9 +118,16 @@
 
     def __init__(self):
         self.mutex = _allocate_lock()
-        self.rng = _Random()
         self.normcase = _os.path.normcase
 
+    @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
--- 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
@@ -126,6 +127,37 @@
         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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -79,6 +79,10 @@
 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.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list