[libvirt] [PATCH v2] snapshot: Don't hose list on deletion failure
Eric Blake
eblake at redhat.com
Mon Nov 5 22:57:33 UTC 2018
ping
On 10/17/18 8:45 PM, Eric Blake wrote:
> If qemuDomainSnapshotDiscard() fails for any reason (rare,
> but possible with an ill-timed ENOMEM or if
> qemuDomainSnapshotForEachQcow2() has problems talking to the
> qemu guest monitor), then an attempt to retry the snapshot
> deletion API will crash because we didn't undo the effects
> of virDomainSnapshotDropParent() temporarily rearranging the
> internal list structures, and the second attempt to drop
> parents will dereference NULL. Fix it by instead noting that
> there are only two callers to qemuDomainSnapshotDiscard(),
> and only one of the two callers wants the parent to be updated;
> thus we can move the call to virDomainSnapshotDropParent()
> into a code path that only gets executed on success.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
>
> ---
> v2: avoid use-after-free
> ---
> src/qemu/qemu_domain.c | 6 ++++--
> src/qemu/qemu_driver.c | 1 -
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index f00f1b3fdb..dd67be5e2a 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -8246,7 +8246,7 @@ int
> qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
> virDomainObjPtr vm,
> virDomainSnapshotObjPtr snap,
> - bool update_current,
> + bool update_parent,
> bool metadata_only)
> {
> char *snapFile = NULL;
> @@ -8275,7 +8275,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
> goto cleanup;
>
> if (snap == vm->current_snapshot) {
> - if (update_current && snap->def->parent) {
> + if (update_parent && snap->def->parent) {
> parentsnap = virDomainSnapshotFindByName(vm->snapshots,
> snap->def->parent);
> if (!parentsnap) {
> @@ -8298,6 +8298,8 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
>
> if (unlink(snapFile) < 0)
> VIR_WARN("Failed to unlink %s", snapFile);
> + if (update_parent)
> + virDomainSnapshotDropParent(snap);
> virDomainSnapshotObjListRemove(vm->snapshots, snap);
>
> ret = 0;
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index a52e2495d5..9f71641dfa 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -16526,7 +16526,6 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
> snap->first_child = NULL;
> ret = 0;
> } else {
> - virDomainSnapshotDropParent(snap);
> ret = qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
> }
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
More information about the libvir-list
mailing list