[libvirt] [PATCHv3 0/6] Fix memory corruption/crash in the connection close callback
Eric Blake
eblake at redhat.com
Tue Apr 9 02:27:24 UTC 2013
On 04/08/2013 07:04 AM, Peter Krempa wrote:
>> Aiee, perhaps a race between a thread freeing a domain object (and the
>> private data) and another thread that happened to acquire the domain
>> object pointer before it was freed? Let me verify if that is possible.
>
> Ufff. The domain objects in the qemu driver don't use reference counting
> to track the lifecycles. Thus it's (Theoretically) possible to acquire a
> lock of a domain object in one thread while another thread happens to
> free the domain object.
>
> I have a reproducer for this issue:
Thanks; I can confirm under valgrind that we have a use after free, with
all sorts of nasty heap corruption potential, after instrumenting my
source a bit more:
diff --git i/src/conf/domain_conf.c w/src/conf/domain_conf.c
index 03e5740..0572822 100644
--- i/src/conf/domain_conf.c
+++ w/src/conf/domain_conf.c
@@ -2240,7 +2240,11 @@ void virDomainObjListRemove(virDomainObjListPtr doms,
virUUIDFormat(dom->def->uuid, uuidstr);
virObjectUnlock(dom);
+ printf(" DEBUG: about to remove dom %s from list\n", uuidstr);
+ sleep(2);
+
virObjectLock(doms);
+ printf(" DEBUG: locked, removing dom %s from list\n", uuidstr);
virHashRemoveEntry(doms->objs, uuidstr);
virObjectUnlock(doms);
}
diff --git i/src/qemu/qemu_driver.c w/src/qemu/qemu_driver.c
index 2c0d7d1..98a49e9 100644
--- i/src/qemu/qemu_driver.c
+++ w/src/qemu/qemu_driver.c
@@ -2297,9 +2297,15 @@ static int qemuDomainGetInfo(virDomainPtr dom,
int err;
unsigned long long balloon;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
+ virUUIDFormat(dom->uuid, uuidstr);
+ printf(" DEBUG: about to look up info on %s\n", uuidstr);
+ sleep(5);
+ printf(" DEBUG: looking up info on %s\n", uuidstr);
+
info->state = virDomainObjGetState(vm, NULL);
if (!virDomainObjIsActive(vm)) {
> and use a bash oneliner to trigger the issue:
>
> virsh undefine domain & sleep .1; virsh dominfo domain
valgrind shows the culprit:
DEBUG: about to remove dom 51c6fc83-65a4-e627-b698-042b00145202 from list
DEBUG: about to look up info on 51c6fc83-65a4-e627-b698-042b00145202
DEBUG: locked, removing dom 51c6fc83-65a4-e627-b698-042b00145202 from list
DEBUG: looking up info on 51c6fc83-65a4-e627-b698-042b00145202
==10033== Thread 6:
==10033== Invalid read of size 4
==10033== at 0x50FF3BB: virDomainObjGetState (domain_conf.c:16264)
==10033== by 0x1B044EF0: qemuDomainGetInfo (qemu_driver.c:2309)
==10033== by 0x515A08C: virDomainGetInfo (libvirt.c:4240)
==10033== by 0x1243CC: remoteDispatchDomainGetInfo
(remote_dispatch.h:1987)
==10033== by 0x1242B1: remoteDispatchDomainGetInfoHelper
(remote_dispatch.h:1963)
==10033== by 0x51D2EE9: virNetServerProgramDispatchCall
(virnetserverprogram.c:439)
==10033== by 0x51D2A60: virNetServerProgramDispatch
(virnetserverprogram.c:305)
==10033== by 0x51D922C: virNetServerProcessMsg (virnetserver.c:162)
==10033== by 0x51D931B: virNetServerHandleJob (virnetserver.c:183)
==10033== by 0x50B97FD: virThreadPoolWorker (virthreadpool.c:144)
==10033== by 0x50B91CE: virThreadHelper (virthreadpthread.c:161)
==10033== by 0x7CAA850: start_thread (pthread_create.c:301)
==10033== Address 0x1daf3a1c is 60 bytes inside a block of size 136 free'd
==10033== at 0x4A063F0: free (vg_replace_malloc.c:446)
==10033== by 0x506C0BD: virFree (viralloc.c:443)
==10033== by 0x50A7366: virObjectUnref (virobject.c:272)
==10033== by 0x50D1112: virDomainObjListDataFree (domain_conf.c:891)
==10033== by 0x5088F3F: virHashRemoveEntry (virhash.c:468)
==10033== by 0x50D48CA: virDomainObjListRemove (domain_conf.c:2248)
==10033== by 0x1AFF1A4A: qemuDomainRemoveInactive (qemu_domain.c:1864)
==10033== by 0x1B04ED30: qemuDomainUndefineFlags (qemu_driver.c:5704)
==10033== by 0x5166490: virDomainUndefineFlags (libvirt.c:8214)
==10033== by 0x131732: remoteDispatchDomainUndefineFlags
(remote_dispatch.h:7066)
==10033== by 0x13161F: remoteDispatchDomainUndefineFlagsHelper
(remote_dispatch.h:7044)
==10033== by 0x51D2EE9: virNetServerProgramDispatchCall
(virnetserverprogram.c:439)
Once again, I'm trying to ascertain how far back this issue appears.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 621 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20130408/1ed594ba/attachment-0001.sig>
More information about the libvir-list
mailing list