c401cc
From 2f2411f9919a69e94d7c31314f2b1a5df30ac3cb Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <2f2411f9919a69e94d7c31314f2b1a5df30ac3cb.1389183249.git.jdenemar@redhat.com>
c401cc
From: Jiri Denemark <jdenemar@redhat.com>
c401cc
Date: Fri, 20 Dec 2013 14:50:02 +0100
c401cc
Subject: [PATCH] qemu: Avoid using stale data in virDomainGetBlockInfo
c401cc
c401cc
CVE-2013-6458
c401cc
c401cc
Generally, every API that is going to begin a job should do that before
c401cc
fetching data from vm->def. However, qemuDomainGetBlockInfo does not
c401cc
know whether it will have to start a job or not before checking vm->def.
c401cc
To avoid using disk alias that might have been freed while we were
c401cc
waiting for a job, we use its copy. In case the disk was removed in the
c401cc
meantime, we will fail with "cannot find statistics for device '...'"
c401cc
error message.
c401cc
c401cc
(cherry picked from commit b799259583bd65c0b2f5042e6c3ff19637ade881)
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_driver.c | 17 ++++++++++++-----
c401cc
 1 file changed, 12 insertions(+), 5 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
c401cc
index 43c072e..f0748c6 100644
c401cc
--- a/src/qemu/qemu_driver.c
c401cc
+++ b/src/qemu/qemu_driver.c
c401cc
@@ -10062,10 +10062,12 @@ cleanup:
c401cc
 }
c401cc
 
c401cc
 
c401cc
-static int qemuDomainGetBlockInfo(virDomainPtr dom,
c401cc
-                                  const char *path,
c401cc
-                                  virDomainBlockInfoPtr info,
c401cc
-                                  unsigned int flags) {
c401cc
+static int
c401cc
+qemuDomainGetBlockInfo(virDomainPtr dom,
c401cc
+                       const char *path,
c401cc
+                       virDomainBlockInfoPtr info,
c401cc
+                       unsigned int flags)
c401cc
+{
c401cc
     virQEMUDriverPtr driver = dom->conn->privateData;
c401cc
     virDomainObjPtr vm;
c401cc
     int ret = -1;
c401cc
@@ -10077,6 +10079,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
c401cc
     int idx;
c401cc
     int format;
c401cc
     virQEMUDriverConfigPtr cfg = NULL;
c401cc
+    char *alias = NULL;
c401cc
 
c401cc
     virCheckFlags(0, -1);
c401cc
 
c401cc
@@ -10183,13 +10186,16 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
c401cc
         virDomainObjIsActive(vm)) {
c401cc
         qemuDomainObjPrivatePtr priv = vm->privateData;
c401cc
 
c401cc
+        if (VIR_STRDUP(alias, disk->info.alias) < 0)
c401cc
+            goto cleanup;
c401cc
+
c401cc
         if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
c401cc
             goto cleanup;
c401cc
 
c401cc
         if (virDomainObjIsActive(vm)) {
c401cc
             qemuDomainObjEnterMonitor(driver, vm);
c401cc
             ret = qemuMonitorGetBlockExtent(priv->mon,
c401cc
-                                            disk->info.alias,
c401cc
+                                            alias,
c401cc
                                             &info->allocation);
c401cc
             qemuDomainObjExitMonitor(driver, vm);
c401cc
         } else {
c401cc
@@ -10203,6 +10209,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
c401cc
     }
c401cc
 
c401cc
 cleanup:
c401cc
+    VIR_FREE(alias);
c401cc
     virStorageFileFreeMetadata(meta);
c401cc
     VIR_FORCE_CLOSE(fd);
c401cc
     if (vm)
c401cc
-- 
c401cc
1.8.5.2
c401cc