ocaml: 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:
Pino Toscano
2017-03-03 13:40:17 +01:00
parent 7527312784
commit 64e1101631

View File

@@ -75,7 +75,7 @@ guestfs_finalize (value gv)
* user deletes events in one of the callbacks that we are
* about to invoke, resulting in a double-free. XXX
*/
size_t len, i;
size_t len;
value **roots = get_all_event_callbacks (g, &len);
/* Close the handle: this could invoke callbacks from the list
@@ -85,11 +85,14 @@ guestfs_finalize (value gv)
guestfs_close (g);
/* Now unregister the global roots. */
for (i = 0; i < len; ++i) {
caml_remove_generational_global_root (roots[i]);
free (roots[i]);
if (len > 0) {
size_t i;
for (i = 0; i < len; ++i) {
caml_remove_generational_global_root (roots[i]);
free (roots[i]);
}
free (roots);
}
free (roots);
}
}
@@ -310,6 +313,10 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
root = 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 (value *) * (*len_rtn));
if (r == NULL) caml_raise_out_of_memory ();