- Fix memory corruption in legacy Xen driver

0e671a16-CVE-2013-4239.patch
  bnc#834598
- Upstream patches to fix dumpxml in legacy Xen driver
  9d0557b9-legacy-xen-double-free.patch,
  d7a45bf2-legacy-xen-dumpxml.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=294
This commit is contained in:
James Fehlig 2013-08-13 16:50:35 +00:00 committed by Git OBS Bridge
parent 10c35258ed
commit 0a26adabe1
8 changed files with 347 additions and 9 deletions

View File

@ -0,0 +1,60 @@
commit 0e671a1646df543eab683b38f6644f70d12fbee1
Author: Jim Fehlig <jfehlig@suse.com>
Date: Mon Aug 5 10:27:23 2013 -0600
xen: fix memory corruption in legacy driver
Commit 632180d1 introduced memory corruption in xenDaemonListDefinedDomains
by starting to populate the names array at index -1, causing all sorts
of havoc in libvirtd such as aborts like the following
*** Error in `/usr/sbin/libvirtd': double free or corruption (out): 0x00007fffe00ccf20 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7abf6)[0x7ffff3fa0bf6]
/lib64/libc.so.6(+0x7b973)[0x7ffff3fa1973]
/lib64/libc.so.6(xdr_array+0xde)[0x7ffff403cbae]
/usr/sbin/libvirtd(+0x50251)[0x5555555a4251]
/lib64/libc.so.6(xdr_free+0x15)[0x7ffff403ccd5]
/usr/lib64/libvirt.so.0(+0x1fad34)[0x7ffff76b1d34]
/usr/lib64/libvirt.so.0(virNetServerProgramDispatch+0x1fc)[0x7ffff76b16f1]
/usr/lib64/libvirt.so.0(+0x1f214a)[0x7ffff76a914a]
/usr/lib64/libvirt.so.0(+0x1f222d)[0x7ffff76a922d]
/usr/lib64/libvirt.so.0(+0xbcc4f)[0x7ffff7573c4f]
/usr/lib64/libvirt.so.0(+0xbc5e5)[0x7ffff75735e5]
/lib64/libpthread.so.0(+0x7e0f)[0x7ffff48f7e0f]
/lib64/libc.so.6(clone+0x6d)[0x7ffff400e7dd]
Fix by initializing ret to 0 and only setting to error on failure path.
Index: libvirt-1.1.1/src/xen/xend_internal.c
===================================================================
--- libvirt-1.1.1.orig/src/xen/xend_internal.c
+++ libvirt-1.1.1/src/xen/xend_internal.c
@@ -2896,7 +2896,7 @@ xenDaemonListDefinedDomains(virConnectPt
{
struct sexpr *root = NULL;
size_t i;
- int ret = -1;
+ int ret = 0;
struct sexpr *_for_i, *node;
if (maxnames == 0)
@@ -2919,16 +2919,15 @@ xenDaemonListDefinedDomains(virConnectPt
break;
}
- ret = 0;
-
cleanup:
sexpr_free(root);
return ret;
error:
- for (i = 0; ret != -1 && i < ret; ++i)
+ for (i = 0; i < ret; ++i)
VIR_FREE(names[i]);
+ ret = -1;
goto cleanup;
}

View File

@ -0,0 +1,24 @@
commit 9d0557b9655fe4a3f31af2e1cc2f33de8acfaa7d
Author: Stefan Bader <stefan.bader@canonical.com>
Date: Wed Jul 31 11:59:21 2013 +0200
xen: Avoid double free of virDomainDef in xenDaemonCreateXML
The virDomainDef is allocated by the caller and also used after
calling to xenDaemonCreateXML. So it must not get freed by the
callee.
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Index: libvirt-1.1.1/src/xen/xend_internal.c
===================================================================
--- libvirt-1.1.1.orig/src/xen/xend_internal.c
+++ libvirt-1.1.1/src/xen/xend_internal.c
@@ -2171,7 +2171,6 @@ xenDaemonCreateXML(virConnectPtr conn, v
if (xenDaemonDomainResume(conn, def) < 0)
goto error;
- virDomainDefFree(def);
return 0;
error:

View File

@ -0,0 +1,238 @@
commit d7a45bf22368161869963b92a0a1d5599590fdf5
Author: Stefan Bader <stefan.bader@canonical.com>
Date: Tue Aug 6 12:28:58 2013 +0100
xen: Use internal interfaces in xenDomainUsedCpus
Since commit 95e18efd most public interfaces (xenUnified...) obtain
a virDomainDefPtr via xenGetDomainDefFor...() which take the unified
lock.
This is already taken before calling xenDomainUsedCpus(), so we get
a deadlock for active guests. Avoid this by splitting up
xenUnifiedDomainGetVcpusFlags() and xenUnifiedDomainGetVcpus() into
public and private function calls (which get the virDomainDefPtr passed)
and use those in xenDomainUsedCpus().
xenDomainUsedCpus
...
nb_vcpu = xenUnifiedDomainGetMaxVcpus(dom);
return xenUnifiedDomainGetVcpusFlags(...)
...
if (!(def = xenGetDomainDefForDom(dom)))
return xenGetDomainDefForUUID(dom->conn, dom->uuid);
...
ret = xenHypervisorLookupDomainByUUID(conn, uuid);
...
xenUnifiedLock(priv);
name = xenStoreDomainGetName(conn, id);
xenUnifiedUnlock(priv);
...
if ((ncpus = xenUnifiedDomainGetVcpus(dom, cpuinfo, nb_vcpu,
...
if (!(def = xenGetDomainDefForDom(dom)))
[again like above]
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Index: libvirt-1.1.1/src/xen/xen_driver.c
===================================================================
--- libvirt-1.1.1.orig/src/xen/xen_driver.c
+++ libvirt-1.1.1/src/xen/xen_driver.c
@@ -73,12 +73,19 @@
static int
xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
+
static int
-xenUnifiedDomainGetMaxVcpus(virDomainPtr dom);
+xenUnifiedDomainGetVcpusFlagsInternal(virDomainPtr dom,
+ virDomainDefPtr def,
+ unsigned int flags);
+
static int
-xenUnifiedDomainGetVcpus(virDomainPtr dom,
- virVcpuInfoPtr info, int maxinfo,
- unsigned char *cpumaps, int maplen);
+xenUnifiedDomainGetVcpusInternal(virDomainPtr dom,
+ virDomainDefPtr def,
+ virVcpuInfoPtr info,
+ int maxinfo,
+ unsigned char *cpumaps,
+ int maplen);
static bool is_privileged = false;
@@ -173,6 +180,7 @@ xenNumaInit(virConnectPtr conn) {
/**
* xenDomainUsedCpus:
* @dom: the domain
+ * @def: the domain definition
*
* Analyze which set of CPUs are used by the domain and
* return a string providing the ranges.
@@ -181,7 +189,7 @@ xenNumaInit(virConnectPtr conn) {
* NULL if the domain uses all CPU or in case of error.
*/
char *
-xenDomainUsedCpus(virDomainPtr dom)
+xenDomainUsedCpus(virDomainPtr dom, virDomainDefPtr def)
{
char *res = NULL;
int ncpus;
@@ -202,7 +210,9 @@ xenDomainUsedCpus(virDomainPtr dom)
if (priv->nbNodeCpus <= 0)
return NULL;
- nb_vcpu = xenUnifiedDomainGetMaxVcpus(dom);
+ nb_vcpu = xenUnifiedDomainGetVcpusFlagsInternal(dom, def,
+ (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
if (nb_vcpu <= 0)
return NULL;
if (xenUnifiedNodeGetInfo(dom->conn, &nodeinfo) < 0)
@@ -217,8 +227,8 @@ xenDomainUsedCpus(virDomainPtr dom)
VIR_ALLOC_N(cpumap, nb_vcpu * cpumaplen) < 0)
goto done;
- if ((ncpus = xenUnifiedDomainGetVcpus(dom, cpuinfo, nb_vcpu,
- cpumap, cpumaplen)) >= 0) {
+ if ((ncpus = xenUnifiedDomainGetVcpusInternal(dom, def, cpuinfo, nb_vcpu,
+ cpumap, cpumaplen)) >= 0) {
for (n = 0; n < ncpus; n++) {
for (m = 0; m < priv->nbNodeCpus; m++) {
bool used;
@@ -1416,54 +1426,62 @@ cleanup:
}
static int
-xenUnifiedDomainGetVcpus(virDomainPtr dom,
- virVcpuInfoPtr info, int maxinfo,
- unsigned char *cpumaps, int maplen)
+xenUnifiedDomainGetVcpusInternal(virDomainPtr dom,
+ virDomainDefPtr def,
+ virVcpuInfoPtr info,
+ int maxinfo,
+ unsigned char *cpumaps,
+ int maplen)
{
xenUnifiedPrivatePtr priv = dom->conn->privateData;
- virDomainDefPtr def = NULL;
int ret = -1;
- if (!(def = xenGetDomainDefForDom(dom)))
- goto cleanup;
-
- if (virDomainGetVcpusEnsureACL(dom->conn, def) < 0)
- goto cleanup;
-
if (dom->id < 0) {
if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot get VCPUs of inactive domain"));
- goto cleanup;
} else {
- ret = xenDaemonDomainGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen);
+ ret = xenDaemonDomainGetVcpus(dom->conn, def, info, maxinfo,
+ cpumaps, maplen);
}
} else {
- ret = xenHypervisorGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen);
+ ret = xenHypervisorGetVcpus(dom->conn, def, info, maxinfo, cpumaps,
+ maplen);
}
-cleanup:
- virDomainDefFree(def);
return ret;
}
static int
-xenUnifiedDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+xenUnifiedDomainGetVcpus(virDomainPtr dom,
+ virVcpuInfoPtr info, int maxinfo,
+ unsigned char *cpumaps, int maplen)
{
- xenUnifiedPrivatePtr priv = dom->conn->privateData;
virDomainDefPtr def = NULL;
int ret = -1;
- virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
- VIR_DOMAIN_VCPU_CONFIG |
- VIR_DOMAIN_VCPU_MAXIMUM, -1);
-
if (!(def = xenGetDomainDefForDom(dom)))
goto cleanup;
- if (virDomainGetVcpusFlagsEnsureACL(dom->conn, def) < 0)
+ if (virDomainGetVcpusEnsureACL(dom->conn, def) < 0)
goto cleanup;
+ ret = xenUnifiedDomainGetVcpusInternal(dom, def, info, maxinfo, cpumaps,
+ maplen);
+
+cleanup:
+ virDomainDefFree(def);
+ return ret;
+}
+
+static int
+xenUnifiedDomainGetVcpusFlagsInternal(virDomainPtr dom,
+ virDomainDefPtr def,
+ unsigned int flags)
+{
+ xenUnifiedPrivatePtr priv = dom->conn->privateData;
+ int ret = -1;
+
if (dom->id < 0) {
if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
ret = xenXMDomainGetVcpusFlags(dom->conn, def, flags);
@@ -1476,6 +1494,27 @@ xenUnifiedDomainGetVcpusFlags(virDomainP
ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags);
}
+ return ret;
+}
+
+static int
+xenUnifiedDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
+ virDomainDefPtr def = NULL;
+ int ret = -1;
+
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ if (!(def = xenGetDomainDefForDom(dom)))
+ goto cleanup;
+
+ if (virDomainGetVcpusFlagsEnsureACL(dom->conn, def) < 0)
+ goto cleanup;
+
+ ret = xenUnifiedDomainGetVcpusFlagsInternal(dom, def, flags);
+
cleanup:
virDomainDefFree(def);
return ret;
@@ -1507,7 +1546,7 @@ xenUnifiedDomainGetXMLDesc(virDomainPtr
} else {
char *cpus;
xenUnifiedLock(priv);
- cpus = xenDomainUsedCpus(dom);
+ cpus = xenDomainUsedCpus(dom, minidef);
xenUnifiedUnlock(priv);
def = xenDaemonDomainGetXMLDesc(dom->conn, minidef, cpus);
VIR_FREE(cpus);
Index: libvirt-1.1.1/src/xen/xen_driver.h
===================================================================
--- libvirt-1.1.1.orig/src/xen/xen_driver.h
+++ libvirt-1.1.1/src/xen/xen_driver.h
@@ -187,7 +187,7 @@ struct _xenUnifiedPrivate {
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
-char *xenDomainUsedCpus(virDomainPtr dom);
+char *xenDomainUsedCpus(virDomainPtr dom, virDomainDefPtr def);
virDomainXMLOptionPtr xenDomainXMLConfInit(void);

View File

@ -12,7 +12,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
===================================================================
--- libvirt-1.1.1.orig/src/xen/xend_internal.c
+++ libvirt-1.1.1/src/xen/xend_internal.c
@@ -2207,6 +2207,7 @@ xenDaemonAttachDeviceFlags(virConnectPtr
@@ -2206,6 +2206,7 @@ xenDaemonAttachDeviceFlags(virConnectPtr
virBuffer buf = VIR_BUFFER_INITIALIZER;
char class[8], ref[80];
char *target = NULL;
@ -20,7 +20,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -2305,8 +2306,18 @@ xenDaemonAttachDeviceFlags(virConnectPtr
@@ -2304,8 +2305,18 @@ xenDaemonAttachDeviceFlags(virConnectPtr
}
sexpr = virBufferContentAndReset(&buf);

View File

@ -1,3 +1,13 @@
-------------------------------------------------------------------
Tue Aug 13 10:47:37 MDT 2013 - jfehlig@suse.com
- Fix memory corruption in legacy Xen driver
0e671a16-CVE-2013-4239.patch
bnc#834598
- Upstream patches to fix dumpxml in legacy Xen driver
9d0557b9-legacy-xen-double-free.patch,
d7a45bf2-legacy-xen-dumpxml.patch
-------------------------------------------------------------------
Wed Jul 31 16:53:28 MDT 2013 - jfehlig@suse.com

View File

@ -405,6 +405,9 @@ Source2: libvirtd-relocation-server.fw
Source99: baselibs.conf
# Upstream patches
Patch0: bcef0f01-libxl-console.patch
Patch1: 9d0557b9-legacy-xen-double-free.patch
Patch2: d7a45bf2-legacy-xen-dumpxml.patch
Patch3: 0e671a16-CVE-2013-4239.patch
# Need to go upstream
Patch100: xen-name-for-devid.patch
Patch101: clone.patch
@ -904,6 +907,9 @@ of recent versions of Linux (and other OSes).
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch100 -p1
%patch101
%patch102 -p1

View File

@ -1,9 +1,9 @@
Adjust libvirtd sysconfig file to conform to SUSE standards
Index: libvirt-1.1.0/daemon/libvirtd.sysconf
Index: libvirt-1.1.1/daemon/libvirtd.sysconf
===================================================================
--- libvirt-1.1.0.orig/daemon/libvirtd.sysconf
+++ libvirt-1.1.0/daemon/libvirtd.sysconf
--- libvirt-1.1.1.orig/daemon/libvirtd.sysconf
+++ libvirt-1.1.1/daemon/libvirtd.sysconf
@@ -1,16 +1,25 @@
+## Path: System/Virtualization/libvirt
+

View File

@ -27,7 +27,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
virDomainDeviceDefPtr dev, char *class,
char *ref, int ref_len);
@@ -3316,18 +3316,18 @@ xenDaemonDomainBlockPeek(virConnectPtr c
@@ -3314,18 +3314,18 @@ xenDaemonDomainBlockPeek(virConnectPtr c
* Returns 0 in case of success, -1 in case of failure.
*/
static int
@ -50,7 +50,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
if (dev->data.disk->driverName &&
STREQ(dev->data.disk->driverName, "tap"))
strcpy(class, "tap");
@@ -3337,19 +3337,17 @@ virDomainXMLDevID(virConnectPtr conn,
@@ -3335,19 +3335,17 @@ virDomainXMLDevID(virConnectPtr conn,
else
strcpy(class, "vbd");
@ -81,7 +81,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
char mac[VIR_MAC_STRING_BUFLEN];
virDomainNetDefPtr netdef = dev->data.net;
@@ -3357,16 +3355,22 @@ virDomainXMLDevID(virConnectPtr conn,
@@ -3355,16 +3353,22 @@ virDomainXMLDevID(virConnectPtr conn,
strcpy(class, "vif");
@ -114,7 +114,7 @@ Index: libvirt-1.1.1/src/xen/xend_internal.c
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
@@ -3382,17 +3386,44 @@ virDomainXMLDevID(virConnectPtr conn,
@@ -3380,17 +3384,44 @@ virDomainXMLDevID(virConnectPtr conn,
strcpy(class, "pci");