]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
daemon: Fix crash in virTypedParameterArrayClear
authorEric Blake <eblake@redhat.com>
Wed, 1 Aug 2012 22:14:41 +0000 (16:14 -0600)
committerEric Blake <eblake@redhat.com>
Wed, 1 Aug 2012 22:27:11 +0000 (16:27 -0600)
Daemon uses the following pattern when dispatching APIs with typed
parameters:

    VIR_ALLOC_N(params, nparams);
    virDomain*(dom, params, &nparams, flags);
    virTypedParameterArrayClear(params, nparams);

In case nparams was originally set to 0, virDomain* API would fill it
with the number of typed parameters it can provide and we would use this
number (rather than zero) to clear params. Because VIR_ALLOC* returns
non-NULL pointer even if size is 0, the code would end up walking
through random memory. If we were lucky enough and the memory contained
7 (VIR_TYPED_PARAM_STRING) at the right place, we would try to free a
random pointer and crash.

Let's make sure params stays NULL when nparams is 0.
(cherry picked from commit 6039a2cb49c8af4c68460d2faf365a7e1c686c7b)

Conflicts:

daemon/remote.c - context differences, and fewer call sites

daemon/remote.c

index 245d41caef3bbc553c6d53950e18439ee3aa2c54..568dd1512ebb5ea2c18430938370104c7188811c 100644 (file)
@@ -789,7 +789,7 @@ remoteDispatchDomainGetSchedulerParameters(virNetServerPtr server ATTRIBUTE_UNUS
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
     }
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (nparams && VIR_ALLOC_N(params, nparams) < 0)
         goto no_memory;
 
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
@@ -842,7 +842,7 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServerPtr server ATTRIBUTE
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
     }
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (nparams && VIR_ALLOC_N(params, nparams) < 0)
         goto no_memory;
 
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
@@ -1022,7 +1022,7 @@ remoteDispatchDomainBlockStatsFlags(virNetServerPtr server ATTRIBUTE_UNUSED,
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
     }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
+    if (nparams && VIR_ALLOC_N(params, nparams) < 0) {
         virReportOOMError();
         goto cleanup;
     }
@@ -1500,7 +1500,7 @@ remoteDispatchDomainGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
     }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
+    if (nparams && VIR_ALLOC_N(params, nparams) < 0) {
         virReportOOMError();
         goto cleanup;
     }
@@ -1563,7 +1563,7 @@ remoteDispatchDomainGetBlkioParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
     }
-    if (VIR_ALLOC_N(params, nparams) < 0) {
+    if (nparams && VIR_ALLOC_N(params, nparams) < 0) {
         virReportOOMError();
         goto cleanup;
     }