[Bug 1594936] Re: fix crash in virDomainObjListFindByUUIDInternal

Rafael David Tinoco rafael.tinoco at canonical.com
Tue Jun 21 18:50:59 UTC 2016


commit 616003d6bd5a3d87d6d529ddb6d83715979d903c
Author: Michael Chapman <mike at very.puzzling.org>
Date:   Wed Mar 11 13:19:54 2015 +1100

    domain_conf: fix crash in virDomainObjListFindByUUIDInternal
    
    If a domain object is being removed and looked up concurrently we must
    ensure we unlock the object before unreferencing it, since the latter
    might free the object.
    
    The flaw was introduced in commit feb1a4d792e1c35b1009e69c00bf351b39.
    
    Signed-off-by: Michael Chapman <mike at very.puzzling.org>

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a8f4ce2..83f3ec6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1068,9 +1068,9 @@ virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms,
     if (obj) {
         virObjectLock(obj);
         if (obj->removing) {
+            virObjectUnlock(obj);
             if (ref)
                 virObjectUnref(obj);
-            virObjectUnlock(obj);
             obj = NULL;
         }
     }

-- 
You received this bug notification because you are a member of Ubuntu
OpenStack, which is subscribed to Ubuntu Cloud Archive.
https://bugs.launchpad.net/bugs/1594936

Title:
  fix crash in virDomainObjListFindByUUIDInternal

Status in libvirt package in Ubuntu:
  In Progress

Bug description:
  It was brought to my attention that libvirt might face some crashes
  (dumps were sent to me).

  Following stack trace:

  #0 0x00007f0d3777ae68 in virClassIsDerivedFrom

  156 /** 
  157 * virClassIsDerivedFrom: 
  158 * @klass: the klass to check 
  159 * @parent: the possible parent class 
  160 * 
  161 * Determine if @klass is derived from @parent 
  162 * 
  163 * Return true if @klass is derived from @parent, false otherwise 
  164 */ 
  165 bool virClassIsDerivedFrom(virClassPtr klass, 
  166 virClassPtr parent) 
  167 { 
  168 while (klass) { 
  169 if (klass->magic == parent->magic) *** HERE *** 
  170 return true; 
  171 klass = klass->parent; 
  172 } 
  173 return false; 
  174 } 

  #1 0x00007f0d3777b196 in virObjectIsClass

  348 /** 
  349 * virObjectIsClass: 
  350 * @anyobj: any instance of virObjectPtr 
  351 * @klass: the class to check 
  352 * 
  353 * Checks whether @anyobj is an instance of 
  354 * @klass 
  355 * 
  356 * Returns true if @anyobj is an instance of @klass 
  357 */ 
  358 bool virObjectIsClass(void *anyobj, 
  359 virClassPtr klass) 
  360 { 
  361 virObjectPtr obj = anyobj; 
  362 if (!obj) 
  363 return false; 
  364 
  365 return virClassIsDerivedFrom(obj->klass, klass); *** HERE *** 
  366 } 

  #2 0x00007f0d3777b2b4 in virObjectUnlock

  327 /** 
  328 * virObjectUnlock: 
  329 * @anyobj: any instance of virObjectLockablePtr 
  330 * 
  331 * Release a lock on @anyobj. The lock must have been 
  332 * acquired by virObjectLock. 
  333 */ 
  334 void virObjectUnlock(void *anyobj) 
  335 { 
  336 virObjectLockablePtr obj = anyobj; 
  337 
  338 if (!virObjectIsClass(obj, virObjectLockableClass)) { *** HERE *** 
  339 VIR_WARN("Object %p (%s) is not a virObjectLockable instance", 
  340 obj, obj ? obj->parent.klass->name : "(unknown)"); 
  341 return; 
  342 } 
  343 
  344 virMutexUnlock(&obj->lock); 
  345 } 

  #3 0x00007f0d377a797f in virDomainObjListFindByUUIDInternal

  1052 static virDomainObjPtr 
  1053 virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms, 
  1054 const unsigned char *uuid, 
  1055 bool ref) 
  1056 { 
  1057 char uuidstr[VIR_UUID_STRING_BUFLEN]; 
  1058 virDomainObjPtr obj; 
  1059 
  1060 virObjectLock(doms); 
  1061 virUUIDFormat(uuid, uuidstr); 
  1062 
  1063 obj = virHashLookup(doms->objs, uuidstr); 
  1064 if (ref) { 
  1065 virObjectRef(obj); 
  1066 virObjectUnlock(doms); 
  1067 } 
  1068 if (obj) { 
  1069 virObjectLock(obj); 
  1070 if (obj->removing) { 
  1071 if (ref) 
  1072 virObjectUnref(obj); 
  1073 virObjectUnlock(obj); 
  1074 obj = NULL; 
  1075 } 
  1076 } 
  1077 if (!ref) 
  1078 virObjectUnlock(doms); *** HERE *** 
  1079 return obj; 
  1080 } 

  And the fix:

  https://www.redhat.com/archives/libvir-list/2015-March/msg00531.html

  Object is being unlocked after already cleaned.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1594936/+subscriptions



More information about the Ubuntu-openstack-bugs mailing list