diff options
author | Eric Blake <eblake@redhat.com> | 2012-02-14 13:08:56 -0700 |
---|---|---|
committer | Doug Goldstein <cardoe@cardoe.com> | 2012-02-19 16:53:16 -0600 |
commit | 1656fad7657cd7bddcdb22c2ae736330b1228b17 (patch) | |
tree | c5a3b4350e4c706916e3ccca3440cd8a22af819c | |
parent | daemon: fix logic bug with virAsprintf (diff) | |
download | libvirt-1656fad7657cd7bddcdb22c2ae736330b1228b17.tar.gz libvirt-1656fad7657cd7bddcdb22c2ae736330b1228b17.tar.bz2 libvirt-1656fad7657cd7bddcdb22c2ae736330b1228b17.zip |
snapshot: fix snapshot deletion use-after-free
Bug introduced in commit 35abced. On an inactive domain,
$ virsh snapshot-create-as dom snap
$ virsh snapshot-create dom
$ virsh snapshot-create dom
$ virsh snapshot-delete --children dom snap
could crash libvirtd, due to a use-after-free that results
when the callback freed the current element in the iteration.
* src/conf/domain_conf.c (virDomainSnapshotForEachChild)
(virDomainSnapshotActOnDescendant): Allow iteration to delete
current child.
-rw-r--r-- | src/conf/domain_conf.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f8d0a4ced..da008309b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13325,8 +13325,9 @@ virDomainSnapshotForEachChild(virDomainSnapshotObjPtr snapshot, virDomainSnapshotObjPtr child = snapshot->first_child; while (child) { + virDomainSnapshotObjPtr next = child->sibling; (iter)(child, child->def->name, data); - child = child->sibling; + child = next; } return snapshot->nchildren; @@ -13346,10 +13347,10 @@ virDomainSnapshotActOnDescendant(void *payload, virDomainSnapshotObjPtr obj = payload; struct snapshot_act_on_descendant *curr = data; - (curr->iter)(payload, name, curr->data); curr->number += 1 + virDomainSnapshotForEachDescendant(obj, curr->iter, curr->data); + (curr->iter)(payload, name, curr->data); } /* Run iter(data) on all descendants of snapshot, while ignoring all |