libvirt/src/libxl
John Ferlan 2065499b60 events: Avoid double free possibility on remote call failure
If a remote call fails during event registration (more than likely from
a network failure or remote libvirtd restart timed just right), then when
calling the virObjectEventStateDeregisterID we don't want to call the
registered @freecb function because that breaks our contract that we
would only call it after succesfully returning.  If the @freecb routine
were called, it could result in a double free from properly coded
applications that free their opaque data on failure to register, as seen
in the following details:

    Program terminated with signal 6, Aborted.
    #0  0x00007fc45cba15d7 in raise
    #1  0x00007fc45cba2cc8 in abort
    #2  0x00007fc45cbe12f7 in __libc_message
    #3  0x00007fc45cbe86d3 in _int_free
    #4  0x00007fc45d8d292c in PyDict_Fini
    #5  0x00007fc45d94f46a in Py_Finalize
    #6  0x00007fc45d960735 in Py_Main
    #7  0x00007fc45cb8daf5 in __libc_start_main
    #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.

Resolve this by adding a @doFreeCb boolean in order to avoid calling the
freeCb in virObjectEventStateDeregisterID for any remote call failure in
a remoteConnect*EventRegister* API. For remoteConnect*EventDeregister* calls,
the passed value would be true indicating they should run the freecb if it
exists; whereas, it's false for the remote call failure path.

Patch based on the investigation and initial patch posted by
fangying <fangying1@huawei.com>.
2017-06-25 08:16:04 -04:00
..
libvirtd_libxl.aug libxl: keepalive messages support 2016-02-09 21:14:12 -07:00
libxl_capabilities.c libxl: report numa sibling distances on host capabilities 2017-05-10 17:15:25 -06:00
libxl_capabilities.h libxl: implement connectGetDomainCapabilities 2016-06-13 14:13:17 -06:00
libxl_conf.c Use ATTRIBUTE_FALLTHROUGH 2017-06-12 19:11:30 -04:00
libxl_conf.h libxl: set nestedhvm for mode host-passthrough 2017-04-27 15:05:44 -06:00
libxl_domain.c virDomainXMLOption: Introduce virDomainABIStabilityDomain 2017-06-05 09:08:52 +02:00
libxl_domain.h libxl: add a flag to mark guests as tainted by a hook 2016-08-02 14:20:31 +02:00
libxl_driver.c events: Avoid double free possibility on remote call failure 2017-06-25 08:16:04 -04:00
libxl_driver.h libxl: Use standard format for source file copyright notice 2013-09-03 23:53:48 -06:00
libxl_logger.c libxl: define a per-domain logger. 2017-01-11 09:32:47 +01:00
libxl_logger.h libxl: define a per-domain logger. 2017-01-11 09:32:47 +01:00
libxl_migration.c virGetDomain: Set domain ID too 2017-04-03 08:35:57 +02:00
libxl_migration.h libxl: add tunnelled migration support 2017-02-15 14:47:14 -07:00
libxl.conf libxl: keepalive messages support 2016-02-09 21:14:12 -07:00
test_libvirtd_libxl.aug.in libxl: keepalive messages support 2016-02-09 21:14:12 -07:00