[libvirt] Double deference error in libvirt_virConnectDomainEventRegisterAny

fangying fangying1 at huawei.com
Fri May 26 08:39:17 UTC 2017


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 ?




More information about the libvir-list mailing list