diff options
author | Jiri Denemark <jdenemar@redhat.com> | 2013-12-20 14:50:02 +0100 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2014-01-15 11:01:53 -0700 |
commit | 12ca0aaf2fc32647d3a570780a2c7467a26b0ecd (patch) | |
tree | 7d49da7a780d6a47173fe243ef5b100cf2b25c1e | |
parent | 59d46c6cd5cb892ce68e83c99c14023f29e073a7 (diff) | |
download | libvirt-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.c | 19 |
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) |