Hi,
We'd like to report a double dereference error of 'pyobj_cbData' in
libvirt_virConnectDomainEventRegisterAny.
The bug can be triggered in the situation where 'domainEventRegisterAny' (the
python interface of libvirt_virConnectDomainEventRegisterAny)
is invoked and network connection is coincidently lost (likely libvirtd restarted) at same
time.
We get the following stacktrace when the bug is hit.
Program terminated with signal 6, Aborted.
#0 0x00007fc45cba15d7 in raise () from /usr/lib64/libc.so.6
#1 0x00007fc45cba2cc8 in abort () from /usr/lib64/libc.so.6
#2 0x00007fc45cbe12f7 in __libc_message () from /usr/lib64/libc.so.6
#3 0x00007fc45cbe86d3 in _int_free () from /usr/lib64/libc.so.6
#4 0x00007fc45d8d292c in PyDict_Fini () from /usr/lib64/libpython2.7.so.1.0
#5 0x00007fc45d94f46a in Py_Finalize () from /usr/lib64/libpython2.7.so.1.0
#6 0x00007fc45d960735 in Py_Main () from /usr/lib64/libpython2.7.so.1.0
#7 0x00007fc45cb8daf5 in __libc_start_main () from /usr/lib64/libc.so.6
#8 0x0000000000400721 in _start ()
The double dereference of 'pyobj_cbData' is triggered in the following way:
(1) libvirt_virConnectDomainEventRegisterAny is invoked.
(2) the event is successfully added to the event callback list
(virDomainEventStateRegisterClient in
remoteConnectDomainEventRegisterAny returns 1 which means ok).
(3) when function remoteConnectDomainEventRegisterAny is hit, network connection
disconnected coincidently
(or libvirtd is restarted) in the context of function 'call' then the
connection is lost and the
function 'call' failed, the branch virObjectEventStateDeregisterID is
therefore taken.
(4) 'pyobj_conn' is dereferenced the 1st time in
libvirt_virConnectDomainEventFreeFunc.
(5) 'pyobj_cbData' (refered to pyobj_conn) is dereferenced the 2nd time in
libvirt_virConnectDomainEventRegisterAny.
(6) the double free error is triggered.
static void
libvirt_virConnectDomainEventFreeFunc(void *opaque)
{
PyObject *pyobj_conn = (PyObject*)opaque;
LIBVIRT_ENSURE_THREAD_STATE;
Py_DECREF(pyobj_conn); /* 1st dereference comes here */
LIBVIRT_RELEASE_THREAD_STATE;
}
static PyObject *
libvirt_virConnectDomainEventRegisterAny(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) {
...
Py_INCREF(pyobj_cbData);
LIBVIRT_BEGIN_ALLOW_THREADS;
ret = virConnectDomainEventRegisterAny(conn, dom, eventID,
cb, pyobj_cbData,
libvirt_virConnectDomainEventFreeFunc);
if (ret < 0) {
Py_DECREF(pyobj_cbData); /* 2nd dereference comes here */
}
}
Currently we cannot find a good solution to fix this problem, could anyone guide us to
fix it ?