Mark McLoughlin 36aee5
From 80965bff6d46dea1808c8bbf02f50f0e289a0e65 Mon Sep 17 00:00:00 2001
Mark McLoughlin 36aee5
From: Daniel P. Berrange <berrange@redhat.com>
Mark McLoughlin 36aee5
Date: Mon, 29 Jun 2009 10:41:56 +0000
Mark McLoughlin 36aee5
Subject: [PATCH] Fix crash in QEMU driver with bad capabilities data
Mark McLoughlin 36aee5
Mark McLoughlin 36aee5
---
Mark McLoughlin 36aee5
 src/qemu_driver.c |   80 +++++++++++++++++++++++++++++++++++-----------------
Mark McLoughlin 36aee5
 1 files changed, 54 insertions(+), 26 deletions(-)
Mark McLoughlin 36aee5
Mark McLoughlin 36aee5
diff -up libvirt-0.6.2/src/qemu_driver.c.bad-caps libvirt-0.6.2/src/qemu_driver.c
Mark McLoughlin 36aee5
--- libvirt-0.6.2/src/qemu_driver.c.bad-caps	2009-07-03 10:07:03.275252815 +0100
Mark McLoughlin 36aee5
+++ libvirt-0.6.2/src/qemu_driver.c	2009-07-03 10:08:52.143502961 +0100
Mark McLoughlin 36aee5
@@ -360,12 +360,43 @@ next:
Mark McLoughlin 36aee5
     return 0;
Mark McLoughlin 36aee5
 }
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+static int
Mark McLoughlin 36aee5
+qemudSecurityCapsInit(virSecurityDriverPtr secdrv,
Mark McLoughlin 36aee5
+                      virCapsPtr caps)
Mark McLoughlin 36aee5
+{
Mark McLoughlin 36aee5
+    const char *doi, *model;
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    doi = virSecurityDriverGetDOI(secdrv);
Mark McLoughlin 36aee5
+    model = virSecurityDriverGetModel(secdrv);
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    caps->host.secModel.model = strdup(model);
Mark McLoughlin 36aee5
+    if (!caps->host.secModel.model) {
Mark McLoughlin 36aee5
+        char ebuf[1024];
Mark McLoughlin 36aee5
+        VIR_ERROR(_("Failed to copy secModel model: %s"),
Mark McLoughlin 36aee5
+                  virStrerror(errno, ebuf, sizeof ebuf));
Mark McLoughlin 36aee5
+        return -1;
Mark McLoughlin 36aee5
+    }
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    caps->host.secModel.doi = strdup(doi);
Mark McLoughlin 36aee5
+    if (!caps->host.secModel.doi) {
Mark McLoughlin 36aee5
+        char ebuf[1024];
Mark McLoughlin 36aee5
+        VIR_ERROR(_("Failed to copy secModel DOI: %s"),
Mark McLoughlin 36aee5
+                  virStrerror(errno, ebuf, sizeof ebuf));
Mark McLoughlin 36aee5
+        return -1;
Mark McLoughlin 36aee5
+    }
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    VIR_DEBUG("Initialized caps for security driver \"%s\" with "
Mark McLoughlin 36aee5
+              "DOI \"%s\"", model, doi);
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    return 0;
Mark McLoughlin 36aee5
+}
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
 static int
Mark McLoughlin 36aee5
 qemudSecurityInit(struct qemud_driver *qemud_drv)
Mark McLoughlin 36aee5
 {
Mark McLoughlin 36aee5
     int ret;
Mark McLoughlin 36aee5
-    const char *doi, *model;
Mark McLoughlin 36aee5
-    virCapsPtr caps;
Mark McLoughlin 36aee5
     virSecurityDriverPtr security_drv;
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
     ret = virSecurityDriverStartup(&security_drv,
Mark McLoughlin 36aee5
@@ -381,36 +412,17 @@ qemudSecurityInit(struct qemud_driver *q
Mark McLoughlin 36aee5
     }
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
     qemud_drv->securityDriver = security_drv;
Mark McLoughlin 36aee5
-    doi = virSecurityDriverGetDOI(security_drv);
Mark McLoughlin 36aee5
-    model = virSecurityDriverGetModel(security_drv);
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
-    VIR_DEBUG("Initialized security driver \"%s\" with "
Mark McLoughlin 36aee5
-              "DOI \"%s\"", model, doi);
Mark McLoughlin 36aee5
+    VIR_INFO("Initialized security driver %s", security_drv->name);
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
     /*
Mark McLoughlin 36aee5
      * Add security policy host caps now that the security driver is
Mark McLoughlin 36aee5
      * initialized.
Mark McLoughlin 36aee5
      */
Mark McLoughlin 36aee5
-    caps = qemud_drv->caps;
Mark McLoughlin 36aee5
-
Mark McLoughlin 36aee5
-    caps->host.secModel.model = strdup(model);
Mark McLoughlin 36aee5
-    if (!caps->host.secModel.model) {
Mark McLoughlin 36aee5
-        char ebuf[1024];
Mark McLoughlin 36aee5
-        VIR_ERROR(_("Failed to copy secModel model: %s"),
Mark McLoughlin 36aee5
-                  virStrerror(errno, ebuf, sizeof ebuf));
Mark McLoughlin 36aee5
-        return -1;
Mark McLoughlin 36aee5
-    }
Mark McLoughlin 36aee5
+    return qemudSecurityCapsInit(security_drv, qemud_drv->caps);
Mark McLoughlin 36aee5
+}
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
-    caps->host.secModel.doi = strdup(doi);
Mark McLoughlin 36aee5
-    if (!caps->host.secModel.doi) {
Mark McLoughlin 36aee5
-        char ebuf[1024];
Mark McLoughlin 36aee5
-        VIR_ERROR(_("Failed to copy secModel DOI: %s"),
Mark McLoughlin 36aee5
-                  virStrerror(errno, ebuf, sizeof ebuf));
Mark McLoughlin 36aee5
-        return -1;
Mark McLoughlin 36aee5
-    }
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
-    return 0;
Mark McLoughlin 36aee5
-}
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
 /**
Mark McLoughlin 36aee5
  * qemudStartup:
Mark McLoughlin 36aee5
@@ -1852,13 +1864,29 @@ static int qemudGetNodeInfo(virConnectPt
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
 static char *qemudGetCapabilities(virConnectPtr conn) {
Mark McLoughlin 36aee5
     struct qemud_driver *driver = conn->privateData;
Mark McLoughlin 36aee5
+    virCapsPtr caps;
Mark McLoughlin 36aee5
     char *xml = NULL;
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
     qemuDriverLock(driver);
Mark McLoughlin 36aee5
+    if ((caps = qemudCapsInit()) == NULL) {
Mark McLoughlin 36aee5
+        virReportOOMError(conn);
Mark McLoughlin 36aee5
+        goto cleanup;
Mark McLoughlin 36aee5
+    }
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    if (qemu_driver->securityDriver &&
Mark McLoughlin 36aee5
+        qemudSecurityCapsInit(qemu_driver->securityDriver, caps) < 0) {
Mark McLoughlin 36aee5
+        virCapabilitiesFree(caps);
Mark McLoughlin 36aee5
+        virReportOOMError(conn);
Mark McLoughlin 36aee5
+        goto cleanup;
Mark McLoughlin 36aee5
+    }
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
     virCapabilitiesFree(qemu_driver->caps);
Mark McLoughlin 36aee5
-    if ((qemu_driver->caps = qemudCapsInit()) == NULL ||
Mark McLoughlin 36aee5
-        (xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
Mark McLoughlin 36aee5
+    qemu_driver->caps = caps;
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+    if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
Mark McLoughlin 36aee5
         virReportOOMError(conn);
Mark McLoughlin 36aee5
+
Mark McLoughlin 36aee5
+cleanup:
Mark McLoughlin 36aee5
     qemuDriverUnlock(driver);
Mark McLoughlin 36aee5
 
Mark McLoughlin 36aee5
     return xml;