[Python-checkins] cpython (merge 3.6 -> default): Merge 3.6 (os.getrandom)

victor.stinner python-checkins at python.org
Tue Sep 20 17:01:49 EDT 2016


https://hg.python.org/cpython/rev/1cbac6b5d0fb
changeset:   103976:1cbac6b5d0fb
parent:      103974:fe9ca4b93b26
parent:      103975:d31b4de433b7
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Sep 20 23:01:22 2016 +0200
summary:
  Merge 3.6 (os.getrandom)

files:
  Misc/NEWS             |   3 ++
  Modules/posixmodule.c |  32 +++++++++++++++++++-----------
  2 files changed, 23 insertions(+), 12 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -38,6 +38,9 @@
 Library
 -------
 
+- Issue #27778: Fix a memory leak in os.getrandom() when the getrandom() is
+  interrupted by a signal and a signal handler raises a Python exception.
+
 - Issue #28200: Fix memory leak on Windows in the os module (fix
   path_converter() function).
 
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -12047,42 +12047,50 @@
 os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
 /*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
 {
-    char *buffer;
+    PyObject *bytes;
     Py_ssize_t n;
-    PyObject *bytes;
 
     if (size < 0) {
         errno = EINVAL;
         return posix_error();
     }
 
-    buffer = PyMem_Malloc(size);
-    if (buffer == NULL) {
+    bytes = PyBytes_FromStringAndSize(NULL, size);
+    if (bytes == NULL) {
         PyErr_NoMemory();
         return NULL;
     }
 
     while (1) {
-        n = syscall(SYS_getrandom, buffer, size, flags);
+        n = syscall(SYS_getrandom,
+                    PyBytes_AS_STRING(bytes),
+                    PyBytes_GET_SIZE(bytes),
+                    flags);
         if (n < 0 && errno == EINTR) {
             if (PyErr_CheckSignals() < 0) {
-                return NULL;
+                goto error;
             }
+
+            /* getrandom() was interrupted by a signal: retry */
             continue;
         }
         break;
     }
 
     if (n < 0) {
-        PyMem_Free(buffer);
         PyErr_SetFromErrno(PyExc_OSError);
-        return NULL;
-    }
-
-    bytes = PyBytes_FromStringAndSize(buffer, n);
-    PyMem_Free(buffer);
+        goto error;
+    }
+
+    if (n != size) {
+        _PyBytes_Resize(&bytes, n);
+    }
 
     return bytes;
+
+error:
+    Py_DECREF(bytes);
+    return NULL;
 }
 #endif   /* HAVE_GETRANDOM_SYSCALL */
 

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


More information about the Python-checkins mailing list