forked from pool/libvirt
100 lines
3.7 KiB
Diff
100 lines
3.7 KiB
Diff
|
commit 6039a2cb49c8af4c68460d2faf365a7e1c686c7b
|
||
|
Author: Jiri Denemark <jdenemar@redhat.com>
|
||
|
Date: Mon Jul 30 12:14:54 2012 +0200
|
||
|
|
||
|
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.
|
||
|
|
||
|
Index: libvirt-0.9.11.4/daemon/remote.c
|
||
|
===================================================================
|
||
|
--- libvirt-0.9.11.4.orig/daemon/remote.c
|
||
|
+++ libvirt-0.9.11.4/daemon/remote.c
|
||
|
@@ -964,7 +964,7 @@ remoteDispatchDomainGetSchedulerParamete
|
||
|
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)))
|
||
|
@@ -1019,7 +1019,7 @@ remoteDispatchDomainGetSchedulerParamete
|
||
|
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)))
|
||
|
@@ -1200,7 +1200,7 @@ remoteDispatchDomainBlockStatsFlags(virN
|
||
|
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;
|
||
|
}
|
||
|
@@ -1674,7 +1674,7 @@ remoteDispatchDomainGetMemoryParameters(
|
||
|
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;
|
||
|
}
|
||
|
@@ -1739,7 +1739,7 @@ remoteDispatchDomainGetNumaParameters(vi
|
||
|
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;
|
||
|
}
|
||
|
@@ -1804,7 +1804,7 @@ remoteDispatchDomainGetBlkioParameters(v
|
||
|
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;
|
||
|
}
|
||
|
@@ -2064,7 +2064,7 @@ remoteDispatchDomainGetBlockIoTune(virNe
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
- if (VIR_ALLOC_N(params, nparams) < 0) {
|
||
|
+ if (nparams && VIR_ALLOC_N(params, nparams) < 0) {
|
||
|
virReportOOMError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
@@ -3563,7 +3563,7 @@ remoteDispatchDomainGetInterfaceParamete
|
||
|
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;
|
||
|
}
|