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.
This commit is contained in:
parent
75024c6589
commit
ec2319c46d
|
@ -32,6 +32,9 @@ Core and Builtins
|
|||
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).
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue