summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martin@piware.de>2020-11-05 13:38:15 +0100
committerCole Robinson <crobinso@redhat.com>2020-11-08 17:01:40 -0500
commit49a01b5482ee5009f4a59953d21eb8741670f813 (patch)
tree6458b6917455de390737fab3490a934322daf638
parent04ad8df752c11ef5e4ec8f3ef425ed92ecb2533f (diff)
downloadvirt-manager-49a01b5482ee5009f4a59953d21eb8741670f813.tar.gz
virtinst: Fix TOCTOU in pool and volume enumeration
_fetch_all_pools_raw() and _fetch_vols_raw() have a race condition where a pool/volume may disappear (from parallel libvirt operations) in between enumerating and inspecting the objects. _fetch_vols_raw() already expected that failure in the loop, but not for the initial storagePoolLookupByName() call. Also tighten the expected exception: This *should* crash on errors like AttributeError or SystemExit, just not on dynamic libvirt errors. (Bare exceptions are highly frowned upon in Python) https://bugzilla.redhat.com/show_bug.cgi?id=1894359
-rw-r--r--virtinst/connection.py20
1 files changed, 17 insertions, 3 deletions
diff --git a/virtinst/connection.py b/virtinst/connection.py
index b3528c27..fec273b7 100644
--- a/virtinst/connection.py
+++ b/virtinst/connection.py
@@ -192,7 +192,16 @@ class VirtinstConnection(object):
def _fetch_all_pools_raw(self):
dummy1, dummy2, ret = pollhelpers.fetch_pools(
self, {}, lambda obj, ignore: obj)
- return [self._build_pool_raw(poolobj) for poolobj in ret]
+ pools = []
+ for poolobj in ret:
+ # TOCTOU race: a pool may go away in between enumeration and inspection
+ try:
+ pool = self._build_pool_raw(poolobj)
+ except libvirt.libvirtError as e: # pragma: no cover
+ log.debug("Fetching pool XML failed: %s", e)
+ continue
+ pools.append(pool)
+ return pools
def _fetch_all_nodedevs_raw(self):
dummy1, dummy2, ret = pollhelpers.fetch_nodedevs(
@@ -202,7 +211,12 @@ class VirtinstConnection(object):
def _fetch_vols_raw(self, poolxmlobj):
ret = []
- pool = self._libvirtconn.storagePoolLookupByName(poolxmlobj.name)
+ # TOCTOU race: a volume may go away in between enumeration and inspection
+ try:
+ pool = self._libvirtconn.storagePoolLookupByName(poolxmlobj.name)
+ except libvirt.libvirtError as e: # pragma: no cover
+ return ret
+
if pool.info()[0] != libvirt.VIR_STORAGE_POOL_RUNNING:
return ret
@@ -213,7 +227,7 @@ class VirtinstConnection(object):
try:
xml = vol.XMLDesc(0)
ret.append(StorageVolume(weakref.proxy(self), parsexml=xml))
- except Exception as e: # pragma: no cover
+ except libvirt.libvirtError as e: # pragma: no cover
log.debug("Fetching volume XML failed: %s", e)
return ret