From nobody Mon Apr 29 03:48:59 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.zohomail.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 151991118845116.702913368358168; Thu, 1 Mar 2018 05:33:08 -0800 (PST) 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 B3846C04BE02; Thu, 1 Mar 2018 13:33:06 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 27B735D6B4; Thu, 1 Mar 2018 13:33:06 +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 340374A46D; Thu, 1 Mar 2018 13:33:05 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w21DX3JJ024777 for ; Thu, 1 Mar 2018 08:33:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id DE30A60BE7; Thu, 1 Mar 2018 13:33:03 +0000 (UTC) Received: from mx1.redhat.com (ext-mx06.extmail.prod.ext.phx2.redhat.com [10.5.110.30]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8E36160BE3; Thu, 1 Mar 2018 13:32:57 +0000 (UTC) Received: from huawei.com (unknown [45.249.212.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 21C4628217; Thu, 1 Mar 2018 13:32:55 +0000 (UTC) Received: from DGGEMS413-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 405345018D374; Thu, 1 Mar 2018 17:44:20 +0800 (CST) Received: from localhost (10.177.25.200) by DGGEMS413-HUB.china.huawei.com (10.3.19.213) with Microsoft SMTP Server id 14.3.361.1; Thu, 1 Mar 2018 17:44:12 +0800 From: "xinhua.Cao" To: , , , Date: Thu, 1 Mar 2018 17:43:55 +0800 Message-ID: <20180301094355.14380-1-caoxinhua@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.25.200] X-CFilter-Loop: Reflected X-Greylist: Delayed for 03:48:20 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 01 Mar 2018 13:32:56 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 01 Mar 2018 13:32:56 +0000 (UTC) for IP:'45.249.212.32' DOMAIN:'[45.249.212.32]' HELO:'huawei.com' FROM:'caoxinhua@huawei.com' RCPT:'' X-RedHat-Spam-Score: 1.272 * (RDNS_NONE, SPF_HELO_PASS, SPF_PASS) 45.249.212.32 [45.249.212.32] 45.249.212.32 [45.249.212.32] X-Scanned-By: MIMEDefang 2.78 on 10.5.110.30 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: weidong.huang@huawei.com, king.wang@huawei.com, liujunjie23@huawei.com, weifuqiang@huawei.com Subject: [libvirt] [PATCH] bugfix: add lock in ClientClose to avoid data race 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: , 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.31]); Thu, 01 Mar 2018 13:33:07 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: l00425170 When libvirt client registers callback function, remoteDispatchConnectDomainEventCallbackRegisterAny is called, then virInse= rtElementsN will be called to add new callback for struct daemonClientPrivate *priv. But at the same time, if the corresponding socket is closed (one way is to = kill the client process), the close callback remoteClientCloseFunc is called, then remoteFreePrivCallbacks(priv) is called to free priv. So there exists data = race to cause libvirtd coredump. More details, in add callback, when memset for ptrptr (that is priv) is don= e in virExpandN at the process of virInsertElementsN. At this time point, priv c= an be free to be 0x0 when close client. So when the procedure goes to memcpy in virInsertElementsN, the libvirtd wi= ll coredump. And the stack are as follows: Thread 1 (Thread 0x7feadf7fe700 (LWP 8978)): #0 0x00007feb7b77f314 in __memcpy_ssse3_back() from /usr/lib64/libc.so= .6 #1 0x00007feb7e769a82 in memcpy (__len=3D8, __src=3D0x7feadf7fdb58, __dest=3D) at /usr/include/bits/string3.h:51 #2 virInsertElementsN (ptrptr=3Dptrptr@entry=3D0x558e9c36fae8, size=3Dsize@entry=3D8, at=3D, at@entry=3D18446744073709551615, countptr=3Dcountptr@entry=3D0x558e9c36faf0, add=3Dadd@entry=3D1, newelems=3Dnewelems@entry=3D0x7feadf7fdb58, clearOriginal=3DclearOr= iginal@entry=3Dtrue, inPlace=3DinPlace@entry=3Dfalse, report=3Dreport@entry=3Dtrue, domcode=3Ddomcode@entry=3D7, filename=3Dfilename@entry=3D0x558e9af1= 6107 "remote.c", funcname=3Dfuncname@entry=3D0x558e9af24600 <__FUNCTION__.48097> "remoteDispatchConnectDomainEventCallbackRegisterAny", linenr=3Dlin= enr@entry=3D4424) at util/viralloc.c:454 #3 0x0000558e9aed7001 in remoteDispatchConnectDomainEventCallbackRegis= terAny (server=3D, msg=3D, ret=3D0x7feab805e= 6f0, args=3D0x7feab806aa40, rerr=3D0x7feadf7fdc90, client=3D) at remote.c:4422 #4 remoteDispatchConnectDomainEventCallbackRegisterAnyHelper (server=3D, client=3D, msg=3D, rerr=3D0x7feadf7fdc90, args=3D0x7feab806aa40, ret=3D0x7feab805e6f0) at remote_dispatch.h:424 #5 0x0000558e9af0ca48 in virNetServerProgramDispatchCall (msg=3D0x558e9c3925c0, client=3D0x558e9c36f970, server=3D0x558e9c35= 1570, prog=3D0x558e9c367d50) at rpc/virnetserverprogram.c:474 #6 virNetServerProgramDispatch (prog=3D0x558e9c367d50, server=3Dserver@entry=3D0x558e9c351570, cli= ent=3D0x558e9c36f970, msg=3D0x558e9c3925c0) at rpc/virnetserverprogram.c:311 #7 0x0000558e9af085ed in virNetServerProcessMsg (msg=3D, prog=3D, client=3D, srv=3D0x558e9c351570) at rpc/virnetserver.c:148 #8 virNetServerHandleJob (jobOpaque=3D, opaque=3D0x558e9c351570) at rpc/virnetserver.c:169 #9 0x00007feb7e7f1861 in virThreadPoolWorker (opaque=3Dopaque@entry=3D0x558e9c36b5f0) at util/virthreadpool.c:167 #10 0x00007feb7e7f0b78 in virThreadHelper (data=3D) at util/virthread.c:219 #11 0x00007feb7b9fcdc5 in start_thread () from /usr/lib64/libpthread.so= .0 #12 0x00007feb7b72b75d in clone () from /usr/lib64/libc.so.6 Signed-off-by: l00425170 --- src/remote/remote_daemon.h | 2 ++ src/remote/remote_daemon_dispatch.c | 46 +++++++++++++++++++++++++++++++++= +++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_daemon.h b/src/remote/remote_daemon.h index 4467f71..8accafc 100644 --- a/src/remote/remote_daemon.h +++ b/src/remote/remote_daemon.h @@ -76,6 +76,8 @@ struct daemonClientPrivate { virConnectPtr conn; =20 daemonClientStreamPtr streams; + + bool clientClosed; }; =20 =20 diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index fdb0a36..59e69e6 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1752,8 +1752,12 @@ static void remoteClientCloseFunc(virNetServerClient= Ptr client) daemonRemoveAllClientStreams(priv->streams); =20 /* Deregister event delivery callback */ - if (priv->conn) + if (priv->conn) { + virMutexLock(&priv->lock); remoteClientFreePrivateCallbacks(priv); + priv->clientClosed =3D true; + virMutexUnlock(&priv->lock); + } } =20 =20 @@ -3889,6 +3893,11 @@ remoteDispatchConnectDomainEventRegister(virNetServe= rPtr server ATTRIBUTE_UNUSED =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + /* If we call register first, we could append a complete callback * to our array, but on OOM append failure, we'd have to then hope * deregister works to undo our register. So instead we append an @@ -4116,6 +4125,11 @@ remoteDispatchConnectDomainEventRegisterAny(virNetSe= rverPtr server ATTRIBUTE_UNU =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + /* We intentionally do not use VIR_DOMAIN_EVENT_ID_LAST here; any * new domain events added after this point should only use the * modern callback style of RPC. */ @@ -4192,6 +4206,11 @@ remoteDispatchConnectDomainEventCallbackRegisterAny(= virNetServerPtr server ATTRI =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->dom && !(dom =3D get_nonnull_domain(priv->conn, *args->dom))) goto cleanup; @@ -5702,6 +5721,11 @@ remoteDispatchConnectNetworkEventRegisterAny(virNetS= erverPtr server ATTRIBUTE_UN =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->net && !(net =3D get_nonnull_network(priv->conn, *args->net))) goto cleanup; @@ -5824,6 +5848,11 @@ remoteDispatchConnectStoragePoolEventRegisterAny(vir= NetServerPtr server ATTRIBUT =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->pool && !(pool =3D get_nonnull_storage_pool(priv->conn, *args->pool))) goto cleanup; @@ -5945,6 +5974,11 @@ remoteDispatchConnectNodeDeviceEventRegisterAny(virN= etServerPtr server ATTRIBUTE =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->dev && !(dev =3D get_nonnull_node_device(priv->conn, *args->dev))) goto cleanup; @@ -6066,6 +6100,11 @@ remoteDispatchConnectSecretEventRegisterAny(virNetSe= rverPtr server ATTRIBUTE_UNU =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->secret && !(secret =3D get_nonnull_secret(priv->conn, *args->secret))) goto cleanup; @@ -6188,6 +6227,11 @@ qemuDispatchConnectDomainMonitorEventRegister(virNet= ServerPtr server ATTRIBUTE_U =20 virMutexLock(&priv->lock); =20 + if (priv->clientClosed) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection want cl= ose")); + goto cleanup; + } + if (args->dom && !(dom =3D get_nonnull_domain(priv->conn, *args->dom))) goto cleanup; --=20 2.13.3.windows.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list