On Wed, Jul 13, 2011 at 07:36:19AM +0200, Salvatore Bonaccorso wrote: > Hi Guido > > On Tue, Jul 12, 2011 at 11:24:26PM +0200, Guido Günther wrote: > > On Tue, Jul 12, 2011 at 12:29:14PM +0200, Salvatore Bonaccorso wrote: > > > Source: libvirt > > > Version: 0.9.2 > > > Severity: important > > > Tags: security > > > > > > Hi Guido > > > > > > In [1] (CVE-2011-2511) an integer overflow in VirDomainGetVcpus for > > > libvirt is mentioned. This is fixed in new upstream 0.9.3. Here [2] is > > > the patch applied by upstream. Can/should there be an update to for > > > stable (if affected?). > > > > > > [1] http://www.securityfocus.com/bid/48478/info > > > [2] https://www.redhat.com/archives/libvir-list/2011-June/msg01278.html > > > [3] http://security-tracker.debian.org/CVE-2011-2511 > > > > Attached patch fixes the issue for stable. We should also fix #623222 > > while at that. O.k. to upload a version to stable-security? > > Wow thanks for you fast work :-). Note, I have only reported the issue > via BTS, but I'm not in security team. I'm Cc'ing this to the security > team list. Attached is the diff for the upload to stable-security. O.k. to upload? This would address
CVE-2011-1486: Make error reporting in libvirtd thread safe CVE-2011-2511: Fix integer overflow in VirDomainGetVcpus for squeeze. Cheers, -- Guido
diff --git a/debian/changelog b/debian/changelog index 613a08b..bd3ec0d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +libvirt (0.8.3-5+squeeze2) stable-security; urgency=low + + * [ac67c93] CVE-2011-1486: Make error reporting in libvirtd thread safe + (Closes: #623222) + * [eafb3d8] CVE-2011-2511: Fix integer overflow in VirDomainGetVcpus + (Closes: #633630) + + -- Guido Günther <a...@sigxcpu.org> Wed, 13 Jul 2011 20:32:22 +0200 + libvirt (0.8.3-5+squeeze1) stable-security; urgency=low * [0ee351f] [CVE-2011-1146] Add missing checks for read only connections. diff --git a/debian/patches/security/0014-Make-error-reporting-in-libvirtd-thread-safe.patch b/debian/patches/security/0014-Make-error-reporting-in-libvirtd-thread-safe.patch new file mode 100644 index 0000000..bfdcae4 --- /dev/null +++ b/debian/patches/security/0014-Make-error-reporting-in-libvirtd-thread-safe.patch @@ -0,0 +1,1090 @@ +From: =?UTF-8?q?Guido=20G=C3=BCnther?= <a...@sigxcpu.org> +Date: Tue, 12 Jul 2011 22:46:37 +0200 +Subject: Make error reporting in libvirtd thread safe + +Origin: upstream, http://libvirt.org/git/?p=libvirt.git;a=commit;h=f44bfb7fb978c9313ce050a1c4149bf04aa0a670 + +CVE: 2011-1486 +Closes: #623222 + +--- + daemon/dispatch.c | 8 +-- + daemon/remote.c | 216 +++++++++++++++++++++++++++------------------------- + 2 files changed, 114 insertions(+), 110 deletions(-) + +diff --git a/daemon/dispatch.c b/daemon/dispatch.c +index 3028298..6262fa5 100644 +--- a/daemon/dispatch.c ++++ b/daemon/dispatch.c +@@ -113,14 +113,10 @@ void remoteDispatchOOMError (remote_error *rerr) + + + void remoteDispatchConnError (remote_error *rerr, +- virConnectPtr conn) ++ virConnectPtr conn ATTRIBUTE_UNUSED) + { +- virErrorPtr verr; ++ virErrorPtr verr = virGetLastError(); + +- if (conn) +- verr = virConnGetLastError(conn); +- else +- verr = virGetLastError(); + if (verr) + remoteDispatchCopyError(rerr, verr); + else +diff --git a/daemon/remote.c b/daemon/remote.c +index 118654c..a8258ca 100644 +--- a/daemon/remote.c ++++ b/daemon/remote.c +@@ -732,8 +732,8 @@ remoteDispatchDomainGetSchedulerType (struct qemud_server *server ATTRIBUTE_UNUS + + type = virDomainGetSchedulerType (dom, &nparams); + if (type == NULL) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -776,9 +776,9 @@ remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUT + + r = virDomainGetSchedulerParameters (dom, params, &nparams); + if (r == -1) { ++ remoteDispatchConnError(rerr, conn); + virDomainFree(dom); + VIR_FREE(params); +- remoteDispatchConnError(rerr, conn); + return -1; + } + +@@ -883,12 +883,13 @@ remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUT + } + + r = virDomainSetSchedulerParameters (dom, params, nparams); +- virDomainFree(dom); + VIR_FREE(params); + if (r == -1) { + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } ++ virDomainFree(dom); + + return 0; + } +@@ -914,8 +915,8 @@ remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED, + path = args->path; + + if (virDomainBlockStats (dom, path, &stats, sizeof stats) == -1) { +- virDomainFree (dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } + virDomainFree (dom); +@@ -950,8 +951,8 @@ remoteDispatchDomainInterfaceStats (struct qemud_server *server ATTRIBUTE_UNUSED + path = args->path; + + if (virDomainInterfaceStats (dom, path, &stats, sizeof stats) == -1) { +- virDomainFree (dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } + virDomainFree (dom); +@@ -1001,12 +1002,13 @@ remoteDispatchDomainMemoryStats (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + nr_stats = virDomainMemoryStats (dom, stats, args->maxStats, 0); +- virDomainFree (dom); + if (nr_stats == -1) { + VIR_FREE(stats); + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } ++ virDomainFree (dom); + + /* Allocate return buffer */ + if (VIR_ALLOC_N(ret->stats.stats_val, args->maxStats) < 0) { +@@ -1067,8 +1069,8 @@ remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED, + if (virDomainBlockPeek (dom, path, offset, size, + ret->buffer.buffer_val, flags) == -1) { + /* free (ret->buffer.buffer_val); - caller frees */ +- virDomainFree (dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } + virDomainFree (dom); +@@ -1116,8 +1118,8 @@ remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED, + if (virDomainMemoryPeek (dom, offset, size, + ret->buffer.buffer_val, flags) == -1) { + /* free (ret->buffer.buffer_val); - caller frees */ +- virDomainFree (dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } + virDomainFree (dom); +@@ -1143,8 +1145,8 @@ remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainAttachDevice (dom, args->xml) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1169,8 +1171,8 @@ remoteDispatchDomainAttachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virDomainAttachDeviceFlags (dom, args->xml, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1195,8 +1197,8 @@ remoteDispatchDomainUpdateDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virDomainUpdateDeviceFlags (dom, args->xml, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1221,8 +1223,8 @@ remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainCreate (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1247,8 +1249,8 @@ remoteDispatchDomainCreateWithFlags (struct qemud_server *server ATTRIBUTE_UNUSE + } + + if (virDomainCreateWithFlags (dom, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -1321,8 +1323,8 @@ remoteDispatchDomainDestroy (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainDestroy (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1347,8 +1349,8 @@ remoteDispatchDomainDetachDevice (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainDetachDevice (dom, args->xml) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -1374,8 +1376,8 @@ remoteDispatchDomainDetachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virDomainDetachDeviceFlags (dom, args->xml, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -1403,8 +1405,8 @@ remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virDomainGetXMLDesc (dom, args->flags); + if (!ret->xml) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1472,8 +1474,8 @@ remoteDispatchDomainGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainGetAutostart (dom, &ret->autostart) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1499,8 +1501,8 @@ remoteDispatchDomainGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainGetInfo (dom, &info) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -1534,8 +1536,8 @@ remoteDispatchDomainGetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED, + + ret->memory = virDomainGetMaxMemory (dom); + if (ret->memory == 0) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1561,8 +1563,8 @@ remoteDispatchDomainGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED, + + ret->num = virDomainGetMaxVcpus (dom); + if (ret->num == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1589,8 +1591,8 @@ remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSE + + memset(&seclabel, 0, sizeof seclabel); + if (virDomainGetSecurityLabel(dom, &seclabel) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -1661,8 +1663,8 @@ remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this */ + ret->type = virDomainGetOSType (dom); + if (ret->type == NULL) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -1712,10 +1714,10 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED, + info, args->maxinfo, + cpumaps, args->maplen); + if (info_len == -1) { ++ remoteDispatchConnError(rerr, conn); + VIR_FREE(info); + VIR_FREE(cpumaps); + virDomainFree(dom); +- remoteDispatchConnError(rerr, conn); + return -1; + } + +@@ -1825,11 +1827,12 @@ remoteDispatchDomainMigratePerform (struct qemud_server *server ATTRIBUTE_UNUSED + args->cookie.cookie_len, + args->uri, + args->flags, dname, args->resource); +- virDomainFree (dom); + if (r == -1) { + remoteDispatchConnError(rerr, conn); ++ virDomainFree (dom); + return -1; + } ++ virDomainFree (dom); + + return 0; + } +@@ -1961,8 +1964,8 @@ remoteDispatchDomainMigratePrepareTunnel(struct qemud_server *server ATTRIBUTE_U + args->flags, dname, args->resource, + args->dom_xml); + if (r == -1) { +- remoteFreeClientStream(client, stream); + remoteDispatchConnError(rerr, conn); ++ remoteFreeClientStream(client, stream); + return -1; + } + +@@ -2123,8 +2126,8 @@ remoteDispatchDomainPinVcpu (struct qemud_server *server ATTRIBUTE_UNUSED, + (unsigned char *) args->cpumap.cpumap_val, + args->cpumap.cpumap_len); + if (rv == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2149,8 +2152,8 @@ remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainReboot (dom, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2193,8 +2196,8 @@ remoteDispatchDomainResume (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainResume (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2219,8 +2222,8 @@ remoteDispatchDomainSave (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSave (dom, args->to) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2245,8 +2248,8 @@ remoteDispatchDomainCoreDump (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainCoreDump (dom, args->to, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2271,8 +2274,8 @@ remoteDispatchDomainSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSetAutostart (dom, args->autostart) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2297,8 +2300,8 @@ remoteDispatchDomainSetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSetMaxMemory (dom, args->memory) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2323,8 +2326,8 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSetMemory (dom, args->memory) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2349,8 +2352,8 @@ remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSetVcpus (dom, args->nvcpus) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2375,8 +2378,8 @@ remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainShutdown (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2401,8 +2404,8 @@ remoteDispatchDomainSuspend (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainSuspend (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2427,8 +2430,8 @@ remoteDispatchDomainUndefine (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainUndefine (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2520,8 +2523,8 @@ remoteDispatchDomainManagedSave (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainManagedSave (dom, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2547,8 +2550,8 @@ remoteDispatchDomainHasManagedSaveImage (struct qemud_server *server ATTRIBUTE_U + + ret->ret = virDomainHasManagedSaveImage (dom, args->flags); + if (ret->ret == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2573,8 +2576,8 @@ remoteDispatchDomainManagedSaveRemove (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virDomainManagedSaveRemove (dom, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + virDomainFree(dom); +@@ -2633,8 +2636,8 @@ remoteDispatchNetworkCreate (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNetworkCreate (net) == -1) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2703,8 +2706,8 @@ remoteDispatchNetworkDestroy (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNetworkDestroy (net) == -1) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2731,8 +2734,8 @@ remoteDispatchNetworkDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virNetworkGetXMLDesc (net, args->flags); + if (!ret->xml) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2757,8 +2760,8 @@ remoteDispatchNetworkGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNetworkGetAutostart (net, &ret->autostart) == -1) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2785,8 +2788,8 @@ remoteDispatchNetworkGetBridgeName (struct qemud_server *server ATTRIBUTE_UNUSED + /* remoteDispatchClientRequest will free this. */ + ret->name = virNetworkGetBridgeName (net); + if (!ret->name) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2855,8 +2858,8 @@ remoteDispatchNetworkSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNetworkSetAutostart (net, args->autostart) == -1) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -2881,8 +2884,8 @@ remoteDispatchNetworkUndefine (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNetworkUndefine (net) == -1) { +- virNetworkFree(net); + remoteDispatchConnError(rerr, conn); ++ virNetworkFree(net); + return -1; + } + virNetworkFree(net); +@@ -3118,8 +3121,8 @@ remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virInterfaceGetXMLDesc (iface, args->flags); + if (!ret->xml) { +- virInterfaceFree(iface); + remoteDispatchConnError(rerr, conn); ++ virInterfaceFree(iface); + return -1; + } + virInterfaceFree(iface); +@@ -3166,8 +3169,8 @@ remoteDispatchInterfaceUndefine (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virInterfaceUndefine (iface) == -1) { +- virInterfaceFree(iface); + remoteDispatchConnError(rerr, conn); ++ virInterfaceFree(iface); + return -1; + } + virInterfaceFree(iface); +@@ -3192,8 +3195,8 @@ remoteDispatchInterfaceCreate (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virInterfaceCreate (iface, args->flags) == -1) { +- virInterfaceFree(iface); + remoteDispatchConnError(rerr, conn); ++ virInterfaceFree(iface); + return -1; + } + virInterfaceFree(iface); +@@ -3218,8 +3221,8 @@ remoteDispatchInterfaceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virInterfaceDestroy (iface, args->flags) == -1) { +- virInterfaceFree(iface); + remoteDispatchConnError(rerr, conn); ++ virInterfaceFree(iface); + return -1; + } + virInterfaceFree(iface); +@@ -4100,8 +4103,8 @@ remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolCreate (pool, args->flags) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4170,8 +4173,8 @@ remoteDispatchStoragePoolBuild (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolBuild (pool, args->flags) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4197,8 +4200,8 @@ remoteDispatchStoragePoolDestroy (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolDestroy (pool) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4223,8 +4226,8 @@ remoteDispatchStoragePoolDelete (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolDelete (pool, args->flags) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4249,8 +4252,8 @@ remoteDispatchStoragePoolRefresh (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolRefresh (pool, args->flags) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4276,8 +4279,8 @@ remoteDispatchStoragePoolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolGetInfo (pool, &info) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + +@@ -4311,8 +4314,8 @@ remoteDispatchStoragePoolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virStoragePoolGetXMLDesc (pool, args->flags); + if (!ret->xml) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4337,8 +4340,8 @@ remoteDispatchStoragePoolGetAutostart (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virStoragePoolGetAutostart (pool, &ret->autostart) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4409,11 +4412,12 @@ remoteDispatchStoragePoolLookupByVolume (struct qemud_server *server ATTRIBUTE_U + } + + pool = virStoragePoolLookupByVolume (vol); +- virStorageVolFree(vol); + if (pool == NULL) { + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(vol); + return -1; + } ++ virStorageVolFree(vol); + + make_nonnull_storage_pool (&ret->pool, pool); + virStoragePoolFree(pool); +@@ -4438,8 +4442,8 @@ remoteDispatchStoragePoolSetAutostart (struct qemud_server *server ATTRIBUTE_UNU + } + + if (virStoragePoolSetAutostart (pool, args->autostart) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4464,8 +4468,8 @@ remoteDispatchStoragePoolUndefine (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStoragePoolUndefine (pool) == -1) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + virStoragePoolFree(pool); +@@ -4607,11 +4611,12 @@ remoteDispatchStorageVolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + vol = virStorageVolCreateXML (pool, args->xml, args->flags); +- virStoragePoolFree(pool); + if (vol == NULL) { + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } ++ virStoragePoolFree(pool); + + make_nonnull_storage_vol (&ret->vol, vol); + virStorageVolFree(vol); +@@ -4638,19 +4643,21 @@ remoteDispatchStorageVolCreateXmlFrom (struct qemud_server *server ATTRIBUTE_UNU + + clonevol = get_nonnull_storage_vol (conn, args->clonevol); + if (clonevol == NULL) { +- virStoragePoolFree(pool); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } + + newvol = virStorageVolCreateXMLFrom (pool, args->xml, clonevol, + args->flags); +- virStorageVolFree(clonevol); +- virStoragePoolFree(pool); + if (newvol == NULL) { + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(clonevol); ++ virStoragePoolFree(pool); + return -1; + } ++ virStorageVolFree(clonevol); ++ virStoragePoolFree(pool); + + make_nonnull_storage_vol (&ret->vol, newvol); + virStorageVolFree(newvol); +@@ -4675,8 +4682,8 @@ remoteDispatchStorageVolDelete (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStorageVolDelete (vol, args->flags) == -1) { +- virStorageVolFree(vol); + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(vol); + return -1; + } + virStorageVolFree(vol); +@@ -4734,8 +4741,8 @@ remoteDispatchStorageVolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virStorageVolGetInfo (vol, &info) == -1) { +- virStorageVolFree(vol); + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(vol); + return -1; + } + +@@ -4768,8 +4775,8 @@ remoteDispatchStorageVolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virStorageVolGetXMLDesc (vol, args->flags); + if (!ret->xml) { +- virStorageVolFree(vol); + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(vol); + return -1; + } + virStorageVolFree(vol); +@@ -4797,8 +4804,8 @@ remoteDispatchStorageVolGetPath (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->name = virStorageVolGetPath (vol); + if (!ret->name) { +- virStorageVolFree(vol); + remoteDispatchConnError(rerr, conn); ++ virStorageVolFree(vol); + return -1; + } + virStorageVolFree(vol); +@@ -4825,11 +4832,12 @@ remoteDispatchStorageVolLookupByName (struct qemud_server *server ATTRIBUTE_UNUS + } + + vol = virStorageVolLookupByName (pool, args->name); +- virStoragePoolFree(pool); + if (vol == NULL) { + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } ++ virStoragePoolFree(pool); + + make_nonnull_storage_vol (&ret->vol, vol); + virStorageVolFree(vol); +@@ -5066,8 +5074,8 @@ remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED, + + ret->num = virNodeDeviceNumOfCaps(dev); + if (ret->num < 0) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + return -1; + } + +@@ -5112,8 +5120,8 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED, + virNodeDeviceListCaps (dev, ret->names.names_val, + args->maxnames); + if (ret->names.names_len == -1) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + VIR_FREE(ret->names.names_val); + return -1; + } +@@ -5142,8 +5150,8 @@ remoteDispatchNodeDeviceDettach (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNodeDeviceDettach(dev) == -1) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + return -1; + } + +@@ -5171,8 +5179,8 @@ remoteDispatchNodeDeviceReAttach (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNodeDeviceReAttach(dev) == -1) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + return -1; + } + +@@ -5200,8 +5208,8 @@ remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNodeDeviceReset(dev) == -1) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + return -1; + } + +@@ -5252,8 +5260,8 @@ remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNodeDeviceDestroy(dev) == -1) { +- virNodeDeviceFree(dev); + remoteDispatchConnError(rerr, conn); ++ virNodeDeviceFree(dev); + return -1; + } + +@@ -5631,8 +5639,8 @@ static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UN + ret->active = virDomainIsActive(domain); + + if (ret->active < 0) { +- virDomainFree(domain); + remoteDispatchConnError(err, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -5659,8 +5667,8 @@ static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUT + ret->persistent = virDomainIsPersistent(domain); + + if (ret->persistent < 0) { +- virDomainFree(domain); + remoteDispatchConnError(err, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -5687,8 +5695,8 @@ static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE + ret->active = virInterfaceIsActive(iface); + + if (ret->active < 0) { +- virInterfaceFree(iface); + remoteDispatchConnError(err, conn); ++ virInterfaceFree(iface); + return -1; + } + +@@ -5715,8 +5723,8 @@ static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_U + ret->active = virNetworkIsActive(network); + + if (ret->active < 0) { +- virNetworkFree(network); + remoteDispatchConnError(err, conn); ++ virNetworkFree(network); + return -1; + } + +@@ -5743,8 +5751,8 @@ static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBU + ret->persistent = virNetworkIsPersistent(network); + + if (ret->persistent < 0) { +- virNetworkFree(network); + remoteDispatchConnError(err, conn); ++ virNetworkFree(network); + return -1; + } + +@@ -5771,8 +5779,8 @@ static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBU + ret->active = virStoragePoolIsActive(pool); + + if (ret->active < 0) { +- virStoragePoolFree(pool); + remoteDispatchConnError(err, conn); ++ virStoragePoolFree(pool); + return -1; + } + +@@ -5799,8 +5807,8 @@ static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATT + ret->persistent = virStoragePoolIsPersistent(pool); + + if (ret->persistent < 0) { +- virStoragePoolFree(pool); + remoteDispatchConnError(err, conn); ++ virStoragePoolFree(pool); + return -1; + } + +@@ -5895,8 +5903,8 @@ remoteDispatchDomainGetJobInfo (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainGetJobInfo (dom, &info) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -5937,8 +5945,8 @@ remoteDispatchDomainAbortJob (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainAbortJob (dom) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -5966,8 +5974,8 @@ remoteDispatchDomainMigrateSetMaxDowntime(struct qemud_server *server ATTRIBUTE_ + } + + if (virDomainMigrateSetMaxDowntime(dom, args->downtime, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -5996,8 +6004,8 @@ remoteDispatchDomainSnapshotCreateXml (struct qemud_server *server ATTRIBUTE_UNU + + snapshot = virDomainSnapshotCreateXML(domain, args->xml_desc, args->flags); + if (snapshot == NULL) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -6038,12 +6046,12 @@ remoteDispatchDomainSnapshotDumpXml (struct qemud_server *server ATTRIBUTE_UNUSE + rc = 0; + + cleanup: ++ if (rc < 0) ++ remoteDispatchConnError(rerr, conn); + if (snapshot) + virDomainSnapshotFree(snapshot); + if (domain) + virDomainFree(domain); +- if (rc < 0) +- remoteDispatchConnError(rerr, conn); + + return rc; + } +@@ -6067,8 +6075,8 @@ remoteDispatchDomainSnapshotNum (struct qemud_server *server ATTRIBUTE_UNUSED, + + ret->num = virDomainSnapshotNum(domain, args->flags); + if (ret->num == -1) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -6112,9 +6120,9 @@ remoteDispatchDomainSnapshotListNames (struct qemud_server *server ATTRIBUTE_UNU + args->nameslen, + args->flags); + if (ret->names.names_len == -1) { ++ remoteDispatchConnError(rerr, conn); + virDomainFree(domain); + VIR_FREE(ret->names.names_val); +- remoteDispatchConnError(rerr, conn); + return -1; + } + +@@ -6143,8 +6151,8 @@ remoteDispatchDomainSnapshotLookupByName (struct qemud_server *server ATTRIBUTE_ + + snapshot = virDomainSnapshotLookupByName(domain, args->name, args->flags); + if (snapshot == NULL) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -6176,8 +6184,8 @@ remoteDispatchDomainHasCurrentSnapshot(struct qemud_server *server ATTRIBUTE_UNU + + result = virDomainHasCurrentSnapshot(domain, args->flags); + if (result < 0) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -6208,8 +6216,8 @@ remoteDispatchDomainSnapshotCurrent(struct qemud_server *server ATTRIBUTE_UNUSED + + snapshot = virDomainSnapshotCurrent(domain, args->flags); + if (snapshot == NULL) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +@@ -6248,12 +6256,12 @@ remoteDispatchDomainRevertToSnapshot (struct qemud_server *server ATTRIBUTE_UNUS + rc = 0; + + cleanup: ++ if (rc < 0) ++ remoteDispatchConnError(rerr, conn); + if (snapshot) + virDomainSnapshotFree(snapshot); + if (domain) + virDomainFree(domain); +- if (rc < 0) +- remoteDispatchConnError(rerr, conn); + + return rc; + } +@@ -6285,12 +6293,12 @@ remoteDispatchDomainSnapshotDelete (struct qemud_server *server ATTRIBUTE_UNUSED + rc = 0; + + cleanup: ++ if (rc < 0) ++ remoteDispatchConnError(rerr, conn); + if (snapshot) + virDomainSnapshotFree(snapshot); + if (domain) + virDomainFree(domain); +- if (rc < 0) +- remoteDispatchConnError(rerr, conn); + + return rc; + } +@@ -6455,8 +6463,8 @@ remoteDispatchNwfilterUndefine (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virNWFilterUndefine (nwfilter) == -1) { +- virNWFilterFree(nwfilter); + remoteDispatchConnError(rerr, conn); ++ virNWFilterFree(nwfilter); + return -1; + } + virNWFilterFree(nwfilter); +@@ -6518,8 +6526,8 @@ remoteDispatchNwfilterGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED, + /* remoteDispatchClientRequest will free this. */ + ret->xml = virNWFilterGetXMLDesc (nwfilter, args->flags); + if (!ret->xml) { +- virNWFilterFree(nwfilter); + remoteDispatchConnError(rerr, conn); ++ virNWFilterFree(nwfilter); + return -1; + } + virNWFilterFree(nwfilter); +@@ -6566,8 +6574,8 @@ remoteDispatchDomainGetBlockInfo (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + if (virDomainGetBlockInfo (dom, args->path, &info, args->flags) == -1) { +- virDomainFree(dom); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(dom); + return -1; + } + +@@ -6599,8 +6607,8 @@ qemuDispatchMonitorCommand (struct qemud_server *server ATTRIBUTE_UNUSED, + + if (virDomainQemuMonitorCommand(domain, args->cmd, &ret->result, + args->flags) == -1) { +- virDomainFree(domain); + remoteDispatchConnError(rerr, conn); ++ virDomainFree(domain); + return -1; + } + +-- diff --git a/debian/patches/security/0015-Fix-integer-overflow-in-VirDomainGetVcpus.patch b/debian/patches/security/0015-Fix-integer-overflow-in-VirDomainGetVcpus.patch new file mode 100644 index 0000000..3d89937 --- /dev/null +++ b/debian/patches/security/0015-Fix-integer-overflow-in-VirDomainGetVcpus.patch @@ -0,0 +1,152 @@ +From: =?UTF-8?q?Guido=20G=C3=BCnther?= <a...@sigxcpu.org> +Date: Tue, 12 Jul 2011 15:03:09 +0200 +Subject: Fix integer overflow in VirDomainGetVcpus + +Patch taken from upsteam. (CVE-2011-2511) + +Closes: #633630 +--- + daemon/remote.c | 4 ++- + gnulib/lib/intprops.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ + src/libvirt.c | 5 ++- + src/remote/remote_driver.c | 4 ++- + 4 files changed, 70 insertions(+), 4 deletions(-) + +diff --git a/daemon/remote.c b/daemon/remote.c +index a8258ca..4c45044 100644 +--- a/daemon/remote.c ++++ b/daemon/remote.c +@@ -58,6 +58,7 @@ + #include "util.h" + #include "stream.h" + #include "libvirt/libvirt-qemu.h" ++#include "intprops.h" + + #define VIR_FROM_THIS VIR_FROM_REMOTE + #define REMOTE_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__) +@@ -1697,7 +1698,8 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED, + return -1; + } + +- if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) { ++ if (INT_MULTIPLY_OVERFLOW(args->maxinfo, args->maplen) || ++ args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) { + virDomainFree(dom); + remoteDispatchFormatError (rerr, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX")); + return -1; +diff --git a/gnulib/lib/intprops.h b/gnulib/lib/intprops.h +index 6c84df6..e842db1 100644 +--- a/gnulib/lib/intprops.h ++++ b/gnulib/lib/intprops.h +@@ -82,4 +82,65 @@ + including the terminating null. */ + # define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + ++#define INT_MULTIPLY_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) ++ ++/* Return 1 if the expression A <op> B would overflow, ++ where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, ++ assuming MIN and MAX are the minimum and maximum for the result type. ++ Arguments should be free of side effects. */ ++#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ ++ op_result_overflow (a, b, \ ++ _GL_INT_MINIMUM (0 * (b) + (a)), \ ++ _GL_INT_MAXIMUM (0 * (b) + (a))) ++ ++/* The maximum and minimum values for the type of the expression E, ++ after integer promotion. E should not have side effects. */ ++#define _GL_INT_MINIMUM(e) \ ++ (_GL_INT_SIGNED (e) \ ++ ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ ++ : _GL_INT_CONVERT (e, 0)) ++#define _GL_INT_MAXIMUM(e) \ ++ (_GL_INT_SIGNED (e) \ ++ ? _GL_SIGNED_INT_MAXIMUM (e) \ ++ : _GL_INT_NEGATE_CONVERT (e, 1)) ++#define _GL_SIGNED_INT_MAXIMUM(e) \ ++ (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) ++ ++/* Return 1 if the integer expression E, after integer promotion, has ++ a signed type. */ ++#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) ++ ++/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see ++ <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>. */ ++#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) ++ ++/* Return an integer value, converted to the same type as the integer ++ expression E after integer type promotion. V is the unconverted value. */ ++#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) ++ ++/* True if the signed integer expression E uses two's complement. */ ++#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) ++ ++#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ ++ (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ ++ || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) ++ ++/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. Avoid && and || as they tickle ++ bugs in Sun C 5.11 2010/08/13 and other compilers; see ++ <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */ ++#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ ++ ((b) < 0 \ ++ ? ((a) < 0 \ ++ ? (a) < (max) / (b) \ ++ : (b) == -1 \ ++ ? 0 \ ++ : (min) / (b) < (a)) \ ++ : (b) == 0 \ ++ ? 0 \ ++ : ((a) < 0 \ ++ ? (a) < (min) / (b) \ ++ : (max) / (b) < (a))) ++ + #endif /* GL_INTPROPS_H */ +diff --git a/src/libvirt.c b/src/libvirt.c +index 5e5a758..6981852 100644 +--- a/src/libvirt.c ++++ b/src/libvirt.c +@@ -39,6 +39,7 @@ + #include "uuid.h" + #include "util.h" + #include "memory.h" ++#include "intprops.h" + + #ifndef WITH_DRIVER_MODULES + # ifdef WITH_TEST +@@ -5218,8 +5219,8 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, + + /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not + try to memcpy anything into a NULL pointer. */ +- if ((cpumaps == NULL && maplen != 0) +- || (cpumaps && maplen <= 0)) { ++ if (!cpumaps ? maplen != 0 ++ : (maplen <= 0 || INT_MULTIPLY_OVERFLOW(maxinfo, maplen))) { + virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } +diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c +index 5fab9c1..11b2e21 100644 +--- a/src/remote/remote_driver.c ++++ b/src/remote/remote_driver.c +@@ -82,6 +82,7 @@ + #include "util.h" + #include "event.h" + #include "ignore-value.h" ++#include "intprops.h" + + #define VIR_FROM_THIS VIR_FROM_REMOTE + +@@ -2500,7 +2501,8 @@ remoteDomainGetVcpus (virDomainPtr domain, + maxinfo, REMOTE_VCPUINFO_MAX); + goto done; + } +- if (maxinfo * maplen > REMOTE_CPUMAPS_MAX) { ++ if (INT_MULTIPLY_OVERFLOW(maxinfo, maplen) || ++ maxinfo * maplen > REMOTE_CPUMAPS_MAX) { + remoteError(VIR_ERR_RPC, + _("vCPU map buffer length exceeds maximum: %d > %d"), + maxinfo * maplen, REMOTE_CPUMAPS_MAX); +-- diff --git a/debian/patches/series b/debian/patches/series index ee5072c..e98d06b 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -11,3 +11,5 @@ 0011-OpenVZ-take-veid-from-vmdef-name-when-defining-new-d.patch 0012-OpenVZ-Fix-some-overwritten-error-codes.patch security/0013-Add-missing-checks-for-read-only-connections.patch +security/0014-Make-error-reporting-in-libvirtd-thread-safe.patch +security/0015-Fix-integer-overflow-in-VirDomainGetVcpus.patch