From: Eric Blake Date: Wed, 1 Aug 2012 22:14:41 +0000 (-0600) Subject: daemon: Fix crash in virTypedParameterArrayClear X-Git-Tag: v0.9.6.2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64b8925c3787eeada314e6ebc7cf825ee87276c2;p=thirdparty%2Flibvirt.git daemon: Fix crash in virTypedParameterArrayClear 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 --- diff --git a/daemon/remote.c b/daemon/remote.c index 245d41caef..568dd1512e 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -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; }