mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
python: do not try to malloc 0 elements in get_all_event_callbacks
In case there are no event handlers registered with the handle, get_all_event_callbacks will count 0 elements, trying to malloc a buffer of that size. POSIX says that this can result in either a null pointer, or an unusable pointer. Short-circuit get_all_event_callbacks to allocate nothing when there are no events, making sure to use its results only when there were events.
This commit is contained in:
@@ -71,7 +71,7 @@ guestfs_int_py_close (PyObject *self, PyObject *args)
|
||||
PyThreadState *py_save = NULL;
|
||||
PyObject *py_g;
|
||||
guestfs_h *g;
|
||||
size_t i, len;
|
||||
size_t len;
|
||||
PyObject **callbacks;
|
||||
|
||||
if (!PyArg_ParseTuple (args, (char *) "O:guestfs_close", &py_g))
|
||||
@@ -81,9 +81,14 @@ guestfs_int_py_close (PyObject *self, PyObject *args)
|
||||
/* As in the OCaml bindings, there is a hard to solve case where the
|
||||
* caller can delete a callback from within the callback, resulting
|
||||
* in a double-free here. XXX
|
||||
*
|
||||
* Take care of the result of get_all_event_callbacks: NULL can be
|
||||
* both an error (and some PyErr_* was called), and no events.
|
||||
* 'len' is specifically 0 only in the latter case, so filter that
|
||||
* out.
|
||||
*/
|
||||
callbacks = get_all_event_callbacks (g, &len);
|
||||
if (callbacks == NULL)
|
||||
if (len != 0 && callbacks == NULL)
|
||||
return NULL;
|
||||
|
||||
if (PyEval_ThreadsInitialized ())
|
||||
@@ -92,9 +97,12 @@ guestfs_int_py_close (PyObject *self, PyObject *args)
|
||||
if (PyEval_ThreadsInitialized ())
|
||||
PyEval_RestoreThread (py_save);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
Py_XDECREF (callbacks[i]);
|
||||
free (callbacks);
|
||||
if (len > 0) {
|
||||
size_t i;
|
||||
for (i = 0; i < len; ++i)
|
||||
Py_XDECREF (callbacks[i]);
|
||||
free (callbacks);
|
||||
}
|
||||
|
||||
Py_INCREF (Py_None);
|
||||
return Py_None;
|
||||
@@ -260,6 +268,10 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
|
||||
cb = guestfs_next_private (g, &key);
|
||||
}
|
||||
|
||||
/* No events, so no need to allocate anything. */
|
||||
if (*len_rtn == 0)
|
||||
return NULL;
|
||||
|
||||
/* Copy them into the return array. */
|
||||
r = malloc (sizeof (PyObject *) * (*len_rtn));
|
||||
if (r == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user