From e1cb98b4e999e099e35a532512d886b3778f23af Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 24 May 2019 16:35:38 +0200 Subject: [PATCH] virStoragePoolObjListForEach: Grab a reference for pool object MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Turns out there's one callback that might remove a storage pool during its run: storagePoolUpdateAllState() call storagePoolUpdateStateCallback() which may call virStoragePoolUpdateInactive() which in turn may call virStoragePoolObjRemove(). Problem is that the UpdateStateCallback() sees a storage pool object with just two references: one for each hash table holding the object. If the function ends up calling ObjRemove() then upon removing the object from hash tables those references are gone and thus any subsequent call touching the object is invalid. The solution to this problem is to grab reference for the object we are running iterator with. Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko --- src/conf/virstorageobj.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 0b83c2d2de..5e64467515 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -411,9 +411,13 @@ virStoragePoolObjListForEachCb(void *payload, virStoragePoolObjPtr obj = payload; struct _virStoragePoolObjListForEachData *data = opaque; + /* Grab a reference so that we don't rely only on references grabbed by + * hash table earlier. Remember, an iterator can remove object from the + * hash table. */ + virObjectRef(obj); virObjectLock(obj); data->iter(obj, data->opaque); - virObjectUnlock(obj); + virStoragePoolObjEndAPI(&obj); return 0; } -- 2.39.5