diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-09-20 21:00:59 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-09-20 21:00:59 (GMT) |
commit | ec2319c46d11e8f486e7def785339af5415a3559 (patch) | |
tree | e07dfd50ae27a470fade7c623d2deac6c9fb91c3 /Modules/posixmodule.c | |
parent | 75024c6589539f72af69ce61cd6493b193989c2d (diff) | |
download | cpython-ec2319c46d11e8f486e7def785339af5415a3559.zip cpython-ec2319c46d11e8f486e7def785339af5415a3559.tar.gz cpython-ec2319c46d11e8f486e7def785339af5415a3559.tar.bz2 |
Fix memleak in os.getrandom()
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.
Modify also os_getrandom_impl() to avoid the temporary buffer, use directly a
Python bytes object.
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 470ee92..28d30b0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12047,42 +12047,50 @@ static PyObject * os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) /*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ { - char *buffer; - Py_ssize_t n; PyObject *bytes; + Py_ssize_t n; 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; + goto error; } - bytes = PyBytes_FromStringAndSize(buffer, n); - PyMem_Free(buffer); + if (n != size) { + _PyBytes_Resize(&bytes, n); + } return bytes; + +error: + Py_DECREF(bytes); + return NULL; } #endif /* HAVE_GETRANDOM_SYSCALL */ |