From nobody Thu Mar 28 10:29:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1490633277355795.7876229025445; Mon, 27 Mar 2017 09:47:57 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A8726635E8; Mon, 27 Mar 2017 16:47:55 +0000 (UTC) Received: from colo-mx.corp.redhat.com (unknown [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7A6CE17108; Mon, 27 Mar 2017 16:47:55 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 321F55EC63; Mon, 27 Mar 2017 16:47:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v2RGlfV4022427 for ; Mon, 27 Mar 2017 12:47:42 -0400 Received: by smtp.corp.redhat.com (Postfix) id F1C6C1F8; Mon, 27 Mar 2017 16:47:41 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-76.phx2.redhat.com [10.3.116.76]) by smtp.corp.redhat.com (Postfix) with ESMTP id B01DD1717C for ; Mon, 27 Mar 2017 16:47:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A8726635E8 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A8726635E8 From: John Ferlan To: libvir-list@redhat.com Date: Mon, 27 Mar 2017 12:47:36 -0400 Message-Id: <20170327164737.27053-2-jferlan@redhat.com> In-Reply-To: <20170327164737.27053-1-jferlan@redhat.com> References: <20170327164737.27053-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 1/2] daemon: Rework remoteClientFreeFunc cleanup loops into C macro X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 27 Mar 2017 16:47:56 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Rather than 'n' repetitive code segments, let's create a single macro which will make the code easier to read. Signed-off-by: John Ferlan --- daemon/remote.c | 126 +++++++++++++++++-----------------------------------= ---- 1 file changed, 37 insertions(+), 89 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 5696b43..5cdc53e 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1668,6 +1668,24 @@ void remoteRelayConnectionClosedEvent(virConnectPtr = conn ATTRIBUTE_UNUSED, int r &msg); } =20 +#define DEREG_CB(conn, eventCallbacks, neventCallbacks, deregFcn, name) = \ + do { = \ + size_t i; = \ + for (i =3D 0; i < neventCallbacks; i++) { = \ + int callbackID =3D eventCallbacks[i]->callbackID; = \ + if (callbackID < 0) { = \ + VIR_WARN("unexpected incomplete %s callback %zu", name, i)= ; \ + continue; = \ + } = \ + VIR_DEBUG("Deregistering remote %s event relay %d", = \ + name, callbackID); = \ + eventCallbacks[i]->callbackID =3D -1; = \ + if (deregFcn(conn, callbackID) < 0) = \ + VIR_WARN("unexpected %s event deregister failure", name); = \ + } = \ + VIR_FREE(eventCallbacks); = \ + } while (0); + /* * You must hold lock for at least the client * We don't free stuff here, merely disconnect the client's @@ -1682,98 +1700,27 @@ void remoteClientFreeFunc(void *data) /* Deregister event delivery callback */ if (priv->conn) { virIdentityPtr sysident =3D virIdentityGetSystem(); - size_t i; =20 virIdentitySetCurrent(sysident); =20 - for (i =3D 0; i < priv->ndomainEventCallbacks; i++) { - int callbackID =3D priv->domainEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete domain callback %zu", i); - continue; - } - VIR_DEBUG("Deregistering remote domain event relay %d", - callbackID); - priv->domainEventCallbacks[i]->callbackID =3D -1; - if (virConnectDomainEventDeregisterAny(priv->conn, callbackID)= < 0) - VIR_WARN("unexpected domain event deregister failure"); - } - VIR_FREE(priv->domainEventCallbacks); - - for (i =3D 0; i < priv->nnetworkEventCallbacks; i++) { - int callbackID =3D priv->networkEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete network callback %zu", i); - continue; - } - VIR_DEBUG("Deregistering remote network event relay %d", - callbackID); - priv->networkEventCallbacks[i]->callbackID =3D -1; - if (virConnectNetworkEventDeregisterAny(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected network event deregister failure"); - } - VIR_FREE(priv->networkEventCallbacks); - - for (i =3D 0; i < priv->nstorageEventCallbacks; i++) { - int callbackID =3D priv->storageEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete storage pool callback %zu"= , i); - continue; - } - VIR_DEBUG("Deregistering remote storage pool event relay %d", - callbackID); - priv->storageEventCallbacks[i]->callbackID =3D -1; - if (virConnectStoragePoolEventDeregisterAny(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected storage pool event deregister failure= "); - } - VIR_FREE(priv->storageEventCallbacks); - - for (i =3D 0; i < priv->nnodeDeviceEventCallbacks; i++) { - int callbackID =3D priv->nodeDeviceEventCallbacks[i]->callback= ID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete node device callback %zu",= i); - continue; - } - VIR_DEBUG("Deregistering remote node device event relay %d", - callbackID); - priv->nodeDeviceEventCallbacks[i]->callbackID =3D -1; - if (virConnectNodeDeviceEventDeregisterAny(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected node device event deregister failure"= ); - } - VIR_FREE(priv->nodeDeviceEventCallbacks); - - for (i =3D 0; i < priv->nsecretEventCallbacks; i++) { - int callbackID =3D priv->secretEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete secret callback %zu", i); - continue; - } - VIR_DEBUG("Deregistering remote secret event relay %d", - callbackID); - priv->secretEventCallbacks[i]->callbackID =3D -1; - if (virConnectSecretEventDeregisterAny(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected secret event deregister failure"); - } - VIR_FREE(priv->secretEventCallbacks); - - for (i =3D 0; i < priv->nqemuEventCallbacks; i++) { - int callbackID =3D priv->qemuEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete qemu monitor callback %zu"= , i); - continue; - } - VIR_DEBUG("Deregistering remote qemu monitor event relay %d", - callbackID); - priv->qemuEventCallbacks[i]->callbackID =3D -1; - if (virConnectDomainQemuMonitorEventDeregister(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected qemu monitor event deregister failure= "); - } - VIR_FREE(priv->qemuEventCallbacks); + DEREG_CB(priv->conn, priv->domainEventCallbacks, + priv->ndomainEventCallbacks, + virConnectDomainEventDeregisterAny, "domain"); + DEREG_CB(priv->conn, priv->networkEventCallbacks, + priv->nnetworkEventCallbacks, + virConnectNetworkEventDeregisterAny, "network"); + DEREG_CB(priv->conn, priv->storageEventCallbacks, + priv->nstorageEventCallbacks, + virConnectStoragePoolEventDeregisterAny, "storage"); + DEREG_CB(priv->conn, priv->nodeDeviceEventCallbacks, + priv->nnodeDeviceEventCallbacks, + virConnectNodeDeviceEventDeregisterAny, "node device"); + DEREG_CB(priv->conn, priv->secretEventCallbacks, + priv->nsecretEventCallbacks, + virConnectSecretEventDeregisterAny, "secret"); + DEREG_CB(priv->conn, priv->qemuEventCallbacks, + priv->nqemuEventCallbacks, + virConnectDomainQemuMonitorEventDeregister, "qemu monitor= "); =20 if (priv->closeRegistered) { if (virConnectUnregisterCloseCallback(priv->conn, @@ -1789,6 +1736,7 @@ void remoteClientFreeFunc(void *data) =20 VIR_FREE(priv); } +#undef DEREG_CB =20 =20 static void remoteClientCloseFunc(virNetServerClientPtr client) --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu Mar 28 10:29:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1490633267340420.5387127083085; Mon, 27 Mar 2017 09:47:47 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B9FDE44804; Mon, 27 Mar 2017 16:47:45 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 89E6B183DB; Mon, 27 Mar 2017 16:47:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8613D18523C9; Mon, 27 Mar 2017 16:47:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v2RGlgsQ022432 for ; Mon, 27 Mar 2017 12:47:42 -0400 Received: by smtp.corp.redhat.com (Postfix) id 9BE9C1717C; Mon, 27 Mar 2017 16:47:42 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-76.phx2.redhat.com [10.3.116.76]) by smtp.corp.redhat.com (Postfix) with ESMTP id 57BBD173A0 for ; Mon, 27 Mar 2017 16:47:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B9FDE44804 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B9FDE44804 From: John Ferlan To: libvir-list@redhat.com Date: Mon, 27 Mar 2017 12:47:37 -0400 Message-Id: <20170327164737.27053-3-jferlan@redhat.com> In-Reply-To: <20170327164737.27053-1-jferlan@redhat.com> References: <20170327164737.27053-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 2/2] remote: Fix possible use-after-free when sending event message X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 27 Mar 2017 16:47:46 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Based upon an idea and some research by Wang King and xinhua.Cao . Since we're assigning the 'client' to our callback event lookaside list, it's imperative that we grab a reference to the object; otherwise, when the object is unref'd during virNetServerProcessClients when it's determined that the virNetServerClientIsClosed and the memory is free'd before perhaps the object event state callbacks are run. When a virObjectLock() is run, before sending the message the following trace occurs; #0 0x00007fda223d66d8 in virClassIsDerivedFrom (klass=3D0xdeadbeef, parent=3D0x7fda24c81b40) at util/virobject.c:169 #1 0x00007fda223d6a1e in virObjectIsClass (anyobj=3Danyobj@entry=3D0x7fd9e575b400, klass=3D) at util/virobject.c:365 #2 0x00007fda223d6a44 in virObjectLock (anyobj=3D0x7fd9e575b400) at util/virobject.c:317 #3 0x00007fda22507f71 in virNetServerClientSendMessage (client=3Dclient@entry=3D0x7fd9e575b400, msg=3Dmsg@entry=3D0x7fd9ec= 30de90) at rpc/virnetserverclient.c:1422 #4 0x00007fda230d714d in remoteDispatchObjectEventSend (client=3D0x7fd9e575b400, program=3D0x7fda24c844e0, procnr=3D348, proc=3D0x7fda2310e5e0 , data=3D0x7ffc3857fdb0) at remote.c:3803 #5 0x00007fda230dd71b in remoteRelayDomainEventTunable (conn=3D, dom=3D0x7fda27cd7660, params=3D0x7fda27f3a= ae0, nparams=3D1,opaque=3D0x7fd9e6c99e00) at remote.c:1033 #6 0x00007fda224484cb in virDomainEventDispatchDefaultFunc (conn=3D0x7fda27cd0120, event=3D0x7fda2736ea00, cb=3D0x7fda230dd610 , cbopaque=3D0x7fd9e6c99e00) at conf/domain_event.c:1910 #7 0x00007fda22446871 in virObjectEventStateDispatchCallbacks (callbacks=3D, callbacks=3D, event=3D0x7fda2736ea00,state=3D0x7fda24ca3960) at conf/object_event.c:722 #8 virObjectEventStateQueueDispatch (callbacks=3D0x7fda24c65800, queue=3D0x7ffc3857fe90, state=3D0x7fda= 24ca3960) at conf/object_event.c:736 #9 virObjectEventStateFlush (state=3D0x7fda24ca3960) at conf/object_event.c:814 #10 virObjectEventTimer (timer=3D, opaque=3D0x7fda24ca39= 60) at conf/object_event.c:560 #11 0x00007fda223ae8b9 in virEventPollDispatchTimeouts () at util/vireventpoll.c:458 #12 virEventPollRunOnce () at util/vireventpoll.c:654 #13 0x00007fda223ad1d2 in virEventRunDefaultImpl () at util/virevent.c:314 #14 0x00007fda225046cd in virNetDaemonRun (dmn=3D0x7fda24c775c0) at rpc/virnetdaemon.c:818 #15 0x00007fda230d6351 in main (argc=3D, argv=3D) at libvirtd.c:1623 Signed-off-by: John Ferlan --- daemon/remote.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 5cdc53e..25a29cf 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -124,7 +124,11 @@ remoteDispatchObjectEventSend(virNetServerClientPtr cl= ient, static void remoteEventCallbackFree(void *opaque) { - VIR_FREE(opaque); + daemonClientEventCallbackPtr callback =3D opaque; + if (!callback) + return; + virObjectUnref(callback->client); + VIR_FREE(callback); } =20 =20 @@ -3896,7 +3900,7 @@ remoteDispatchConnectDomainEventRegister(virNetServer= Ptr server ATTRIBUTE_UNUSED */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D VIR_DOMAIN_EVENT_ID_LIFECYCLE; callback->callbackID =3D -1; callback->legacy =3D true; @@ -3923,7 +3927,7 @@ remoteDispatchConnectDomainEventRegister(virNetServer= Ptr server ATTRIBUTE_UNUSED rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virMutexUnlock(&priv->lock); @@ -4131,7 +4135,7 @@ remoteDispatchConnectDomainEventRegisterAny(virNetSer= verPtr server ATTRIBUTE_UNU * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; callback->legacy =3D true; @@ -4158,7 +4162,7 @@ remoteDispatchConnectDomainEventRegisterAny(virNetSer= verPtr server ATTRIBUTE_UNU rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virMutexUnlock(&priv->lock); @@ -4207,7 +4211,7 @@ remoteDispatchConnectDomainEventCallbackRegisterAny(v= irNetServerPtr server ATTRI * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; ref =3D callback; @@ -4234,7 +4238,7 @@ remoteDispatchConnectDomainEventCallbackRegisterAny(v= irNetServerPtr server ATTRI rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(dom); @@ -5717,7 +5721,7 @@ remoteDispatchConnectNetworkEventRegisterAny(virNetSe= rverPtr server ATTRIBUTE_UN * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; ref =3D callback; @@ -5744,7 +5748,7 @@ remoteDispatchConnectNetworkEventRegisterAny(virNetSe= rverPtr server ATTRIBUTE_UN rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(net); @@ -5839,7 +5843,7 @@ remoteDispatchConnectStoragePoolEventRegisterAny(virN= etServerPtr server ATTRIBUT * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; ref =3D callback; @@ -5866,7 +5870,7 @@ remoteDispatchConnectStoragePoolEventRegisterAny(virN= etServerPtr server ATTRIBUT rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(pool); @@ -5960,7 +5964,7 @@ remoteDispatchConnectNodeDeviceEventRegisterAny(virNe= tServerPtr server ATTRIBUTE * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; ref =3D callback; @@ -5987,7 +5991,7 @@ remoteDispatchConnectNodeDeviceEventRegisterAny(virNe= tServerPtr server ATTRIBUTE rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(dev); @@ -6081,7 +6085,7 @@ remoteDispatchConnectSecretEventRegisterAny(virNetSer= verPtr server ATTRIBUTE_UNU * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->eventID =3D args->eventID; callback->callbackID =3D -1; ref =3D callback; @@ -6108,7 +6112,7 @@ remoteDispatchConnectSecretEventRegisterAny(virNetSer= verPtr server ATTRIBUTE_UNU rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(secret); @@ -6197,7 +6201,7 @@ qemuDispatchConnectDomainMonitorEventRegister(virNetS= erverPtr server ATTRIBUTE_U * success, we use 'ref' to save a copy of the pointer. */ if (VIR_ALLOC(callback) < 0) goto cleanup; - callback->client =3D client; + callback->client =3D virObjectRef(client); callback->callbackID =3D -1; ref =3D callback; if (VIR_APPEND_ELEMENT(priv->qemuEventCallbacks, @@ -6224,7 +6228,7 @@ qemuDispatchConnectDomainMonitorEventRegister(virNetS= erverPtr server ATTRIBUTE_U rv =3D 0; =20 cleanup: - VIR_FREE(callback); + remoteEventCallbackFree(callback); if (rv < 0) virNetMessageSaveError(rerr); virObjectUnref(dom); --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list