From nobody Mon May 6 15:19:43 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; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1569430783; cv=none; d=zoho.com; s=zohoarc; b=ogB3+pSYejyLuvlVBV6PXeYXES/hkla9kRQVUw9Q/YR+MpHgDGjRB39WSkFZfGBYI3BxkOXyEaHqJcSIlqjOYdAOFXHywWeg2rSouxslvsXObVorvoFl+m+r3C5sQZHu66HT88gPWqt0Nu16ZFX64UT+f/ufMwueLi9kM+3DeaE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569430783; h=Content-Type:Content-Transfer-Encoding:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To:ARC-Authentication-Results; bh=iYaaIS/ZK5om2zxWV0OTVBfePpk1Uiu2ceX93nKjIuk=; b=RZamK8s5j2qNLK9obba1496+d5tEwjbuCfUSLX5CDYNC6wbxIOsfT8xUezSukHQNkNJwGzz61SbK9lW49BVYAKNW+CEx1xuqPaCHhDC8Q6ugASEWYYcnC2J3NdoJIngWDGKHpp+T6nFD5pdkWzeKrSx3OGf7e7E1DAcdcIlldnE= ARC-Authentication-Results: i=1; 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; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 156943078290639.052387627207054; Wed, 25 Sep 2019 09:59:42 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C75544ACA5; Wed, 25 Sep 2019 16:59:37 +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 3258660F9E; Wed, 25 Sep 2019 16:59:37 +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 2B9864EE68; Wed, 25 Sep 2019 16:59:36 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x8PGvdvj026988 for ; Wed, 25 Sep 2019 12:57:39 -0400 Received: by smtp.corp.redhat.com (Postfix) id E53BD1001B12; Wed, 25 Sep 2019 16:57:39 +0000 (UTC) Received: from vhost2.laine.org (ovpn-116-86.phx2.redhat.com [10.3.116.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9E4D81001B20 for ; Wed, 25 Sep 2019 16:57:36 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Wed, 25 Sep 2019 12:57:32 -0400 Message-Id: <20190925165732.24807-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH] conf: utility function to update entry in def->nets array 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.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 25 Sep 2019 16:59:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" A virDomainNetDef object in a domain's nets array might contain a virDomainHostdevDef, and when this is the case, the domain's hostdevs array will also have a pointer to this embedded hostdev (this is done so that internal functions that need to perform some operation on all hostdevs won't leave out the type=3D'hostdev' network interfaces). When a network device was updated with virDomainUpdateDeviceFlags(), we were replacing the entry in the nets array (and free'ing the original) but forgetting about the pointer in the hostdevs array (which would then point to the now-free'd hostdev contained in the old net object.) This often resulted in a libvirtd crash. The solution is to add a function, virDomainNetUpdate(), called by qemuDomainUpdateDeviceConfig(), that updates the hostdevs array appropriately along with the nets array. Resolves: https://bugzilla.redhat.com/1558934 Signed-off-by: Laine Stump Reviewed-by: Michal Privoznik --- (I actually think that it was a bad idea to have this "reach over" pointer in the hostdevs array (I can say that, since it was my idea :-), and want to eliminate it in favor of using an iterator function for all operations that need to do something to all hostdevs, but this bug exists on old, maintained branches, and I wouldn't want to require backporting anything that disruptive to a stable branch.) Also, I was unable to reproduce the crashes described in the bug report using current upstream code, but could witness (by adding a breakpoint in gdb) the stale pointer when running without this patch, and the correct pointer when running with the patch) src/conf/domain_conf.c | 41 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 6 ++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d638c455d0..2875598eb0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17109,6 +17109,47 @@ virDomainNetRemove(virDomainDefPtr def, size_t i) return net; } =20 + +int +virDomainNetUpdate(virDomainDefPtr def, + size_t netidx, + virDomainNetDefPtr newnet) +{ + size_t hostdevidx; + virDomainNetDefPtr oldnet =3D def->nets[netidx]; + virDomainHostdevDefPtr oldhostdev =3D virDomainNetGetActualHostdev(old= net); + virDomainHostdevDefPtr newhostdev =3D virDomainNetGetActualHostdev(new= net); + + /* + * if newnet or oldnet has a valid hostdev*, we need to update the + * hostdevs list + */ + if (oldhostdev) { + for (hostdevidx =3D 0; hostdevidx < def->nhostdevs; hostdevidx++) { + if (def->hostdevs[hostdevidx] =3D=3D oldhostdev) + break; + } + } + + if (oldhostdev && hostdevidx < def->nhostdevs) { + if (newhostdev) { + /* update existing entry in def->hostdevs */ + def->hostdevs[hostdevidx] =3D newhostdev; + } else { + /* delete oldhostdev from def->hostdevs */ + virDomainHostdevRemove(def, hostdevidx); + } + } else if (newhostdev) { + /* add newhostdev to end of def->hostdevs */ + if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, newhostdev) = < 0) + return -1; + } + + def->nets[netidx] =3D newnet; + return 0; +} + + int virDomainControllerInsert(virDomainDefPtr def, virDomainControllerDefPtr controller) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 57ce5b95dc..c91e8841ee 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3157,6 +3157,7 @@ virDomainNetDefPtr virDomainNetFind(virDomainDefPtr d= ef, const char *device); virDomainNetDefPtr virDomainNetFindByName(virDomainDefPtr def, const char = *ifname); bool virDomainHasNet(virDomainDefPtr def, virDomainNetDefPtr net); int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net); +int virDomainNetUpdate(virDomainDefPtr def, size_t netidx, virDomainNetDef= Ptr newnet); virDomainNetDefPtr virDomainNetRemove(virDomainDefPtr def, size_t i); void virDomainNetRemoveHostdev(virDomainDefPtr def, virDomainNetDefPtr net= ); =20 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 39812227aa..d1534871a9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -508,6 +508,7 @@ virDomainNetSetModelString; virDomainNetTypeFromString; virDomainNetTypeSharesHostView; virDomainNetTypeToString; +virDomainNetUpdate; virDomainNostateReasonTypeFromString; virDomainNostateReasonTypeToString; virDomainObjAssignDef; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0753904472..5f63c4f51e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8786,8 +8786,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, false) < 0) return -1; =20 - virDomainNetDefFree(vmdef->nets[pos]); - vmdef->nets[pos] =3D net; + if (virDomainNetUpdate(vmdef, pos, net)) + return -1; + + virDomainNetDefFree(oldDev.data.net); dev->data.net =3D NULL; break; =20 --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list