diff --git a/libvirt-0.8.3-avoid-resetting-errors.patch b/libvirt-0.8.3-avoid-resetting-errors.patch new file mode 100644 index 0000000..8ae4df2 --- /dev/null +++ b/libvirt-0.8.3-avoid-resetting-errors.patch @@ -0,0 +1,51 @@ +From 452bf160e5bbe0789d706fda95f5919551eb2cac Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Fri, 25 Mar 2011 16:45:45 +0100 +Subject: [PATCH 2/2] daemon: Avoid resetting errors before they are reported + +https://bugzilla.redhat.com/show_bug.cgi?id=690733 + +Commit f44bfb7 was supposed to make sure no additional libvirt API (esp. +*Free) is called before remoteDispatchConnError() is called on error. +However, the patch missed two instances. +(cherry picked from commit 55cc591fc18e87b29febf78dc5b424b7c12f7349) +--- + daemon/remote.c | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/daemon/remote.c b/daemon/remote.c +index a8258ca..7464957 100644 +--- a/daemon/remote.c ++++ b/daemon/remote.c +@@ -4547,12 +4547,13 @@ remoteDispatchStoragePoolListVolumes (struct qemud_server *server ATTRIBUTE_UNUS + ret->names.names_len = + virStoragePoolListVolumes (pool, + ret->names.names_val, args->maxnames); +- virStoragePoolFree(pool); + if (ret->names.names_len == -1) { + VIR_FREE(ret->names.names_val); + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } ++ virStoragePoolFree(pool); + + return 0; + } +@@ -4576,11 +4577,12 @@ remoteDispatchStoragePoolNumOfVolumes (struct qemud_server *server ATTRIBUTE_UNU + } + + ret->num = virStoragePoolNumOfVolumes (pool); +- virStoragePoolFree(pool); + if (ret->num == -1) { + remoteDispatchConnError(rerr, conn); ++ virStoragePoolFree(pool); + return -1; + } ++ virStoragePoolFree(pool); + + return 0; + } +-- +1.7.3.4 + diff --git a/libvirt-0.8.3-threadsafe-libvirtd-error-reporting.patch b/libvirt-0.8.3-threadsafe-libvirtd-error-reporting.patch new file mode 100644 index 0000000..96a7431 --- /dev/null +++ b/libvirt-0.8.3-threadsafe-libvirtd-error-reporting.patch @@ -0,0 +1,1118 @@ +From 7aa857f9e3b3de0a8f86d3d79b626dbe89df68de Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Fri, 25 Mar 2011 16:45:44 +0100 +Subject: [PATCH 1/2] Make error reporting in libvirtd thread safe + +Bug https://bugzilla.redhat.com/show_bug.cgi?id=690733 reported libvirtd +crash during error dispatch. + +The reason is that libvirtd uses remoteDispatchConnError() with non-NULL +conn parameter which means that virConnGetLastError() is used instead of +its thread safe replacement virGetLastError(). + +So when several libvirtd threads are reporting errors at the same time, +the errors can get mixed or corrupted or in case of bad luck libvirtd +itself crashes. + +Since Daniel B. is going to rewrite this code from scratch on top of his +RPC infrastructure, I tried to come up with a minimal fix. Thus, +remoteDispatchConnError() now just ignores its conn argument and always +calls virGetLastError(). However, several callers had to be touched as +well, since no libvirt API is allowed to be called before dispatching +the error. Doing so would reset the error and we would have nothing to +dispatch. As a result of that, the code is not very nice but that +doesn't really make daemon/remote.c worse than it is now :-) And it will +all die soon, which is good. + +The bug report also contains a reproducer in C which detects both mixed +up error messages and libvirtd crash. Before this patch, I was able to +crash libvirtd in about 20 seconds up to 3 minutes depending on number +of CPU cores (more is better) and luck. +(cherry picked from commit f44bfb7fb978c9313ce050a1c4149bf04aa0a670) + +Conflicts: + + daemon/remote.c +--- + 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; + } + +-- +1.7.3.4 + diff --git a/libvirt.spec b/libvirt.spec index f3ad70d..bc29e9d 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -185,7 +185,7 @@ Summary: Library providing a simple API virtualization Name: libvirt Version: 0.8.3 -Release: 7%{?dist}%{?extra_release} +Release: 8%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz @@ -193,6 +193,9 @@ Patch1: %{name}-%{version}-boot-menu.patch Patch2: %{name}-%{version}-octal-addresses.patch Patch3: %{name}-%{version}-read-only-checks.patch Patch4: %{name}-%{version}-fix-var-lib-libvirt-permissions.patch +# Patches 5, 6 CVE-2011-1486 +Patch5: %{name}-%{version}-threadsafe-libvirtd-error-reporting.patch +Patch6: %{name}-%{version}-avoid-resetting-errors.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ @@ -433,6 +436,8 @@ of recent versions of Linux (and other OSes). %patch2 -p1 %patch3 -p0 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 %build %if ! %{with_xen} @@ -923,6 +928,10 @@ fi %endif %changelog +* Tue Apr 5 2011 Laine Stump 0.8.2-8 +- Fix for CVE-2011-1486, error reporting in libvirtd is not thread safe, + bug 693457 + * Mon Apr 4 2011 Laine Stump 0.8.3-7 - fix permissions on /var/lib/libvirt