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

Reply via email to