summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Denemark <jdenemar@redhat.com>2013-12-20 14:50:02 +0100
committerEric Blake <eblake@redhat.com>2014-01-15 11:01:53 -0700
commit12ca0aaf2fc32647d3a570780a2c7467a26b0ecd (patch)
tree7d49da7a780d6a47173fe243ef5b100cf2b25c1e
parent59d46c6cd5cb892ce68e83c99c14023f29e073a7 (diff)
downloadlibvirt-12ca0aaf2fc32647d3a570780a2c7467a26b0ecd.tar.gz
qemu: Avoid using stale data in virDomainGetBlockInfo
CVE-2013-6458 Generally, every API that is going to begin a job should do that before fetching data from vm->def. However, qemuDomainGetBlockInfo does not know whether it will have to start a job or not before checking vm->def. To avoid using disk alias that might have been freed while we were waiting for a job, we use its copy. In case the disk was removed in the meantime, we will fail with "cannot find statistics for device '...'" error message. (cherry picked from commit b799259583bd65c0b2f5042e6c3ff19637ade881) Conflicts: src/qemu/qemu_driver.c - VIR_STRDUP not backported
-rw-r--r--src/qemu/qemu_driver.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d997ee0b86..f9616dd005 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9191,10 +9191,12 @@ cleanup:
}
-static int qemuDomainGetBlockInfo(virDomainPtr dom,
- const char *path,
- virDomainBlockInfoPtr info,
- unsigned int flags) {
+static int
+qemuDomainGetBlockInfo(virDomainPtr dom,
+ const char *path,
+ virDomainBlockInfoPtr info,
+ unsigned int flags)
+{
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
int ret = -1;
@@ -9206,6 +9208,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
int i;
int format;
virQEMUDriverConfigPtr cfg = NULL;
+ char *alias = NULL;
virCheckFlags(0, -1);
@@ -9312,13 +9315,18 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
virDomainObjIsActive(vm)) {
qemuDomainObjPrivatePtr priv = vm->privateData;
+ if (!(alias = strdup(disk->info.alias))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
if (virDomainObjIsActive(vm)) {
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorGetBlockExtent(priv->mon,
- disk->info.alias,
+ alias,
&info->allocation);
qemuDomainObjExitMonitor(driver, vm);
} else {
@@ -9332,6 +9340,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
}
cleanup:
+ VIR_FREE(alias);
virStorageFileFreeMetadata(meta);
VIR_FORCE_CLOSE(fd);
if (vm)