summaryrefslogtreecommitdiffstats
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-09-20 21:00:59 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-09-20 21:00:59 (GMT)
commitec2319c46d11e8f486e7def785339af5415a3559 (patch)
treee07dfd50ae27a470fade7c623d2deac6c9fb91c3 /Modules/posixmodule.c
parent75024c6589539f72af69ce61cd6493b193989c2d (diff)
downloadcpython-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.c28
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 */