From nobody Sun May 5 16:41:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489578586810988.0309619984123; Wed, 15 Mar 2017 04:49:46 -0700 (PDT) Received: from localhost ([::1]:36304 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7Qz-0006cY-Hq for importer@patchew.org; Wed, 15 Mar 2017 07:49:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7Q5-0006bA-NF for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1co7Q4-0003qf-Po for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40470) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1co7Q4-0003qR-J7 for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:44 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (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 8B27480F6D; Wed, 15 Mar 2017 11:48:44 +0000 (UTC) Received: from jason-ThinkPad-T450s.redhat.com (vpn1-6-37.pek2.redhat.com [10.72.6.37]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2FBmaXB031920; Wed, 15 Mar 2017 07:48:41 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8B27480F6D Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jasowang@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8B27480F6D From: Jason Wang To: mst@redhat.com, qemu-devel@nongnu.org Date: Wed, 15 Mar 2017 19:48:30 +0800 Message-Id: <1489578512-14031-2-git-send-email-jasowang@redhat.com> In-Reply-To: <1489578512-14031-1-git-send-email-jasowang@redhat.com> References: <1489578512-14031-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 15 Mar 2017 11:48:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH V4 1/3] virtio: guard against NULL pfn X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cornelia Huck , Paolo Bonzini , Jason Wang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" To avoid access stale memory region cache after reset, this patch check the existence of virtqueue pfn for all exported virtqueue access helpers before trying to use them. Cc: Cornelia Huck Cc: Paolo Bonzini Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- Changes from V2: - return 1 instead of 0 for virtio_queue_empty_*(), and return as early as possible --- hw/virtio/virtio.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index efce4b3..9164579 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -318,6 +318,10 @@ int virtio_queue_ready(VirtQueue *vq) * Called within rcu_read_lock(). */ static int virtio_queue_empty_rcu(VirtQueue *vq) { + if (unlikely(!vq->vring.avail)) { + return 1; + } + if (vq->shadow_avail_idx !=3D vq->last_avail_idx) { return 0; } @@ -329,6 +333,10 @@ int virtio_queue_empty(VirtQueue *vq) { bool empty; =20 + if (unlikely(!vq->vring.avail)) { + return 1; + } + if (vq->shadow_avail_idx !=3D vq->last_avail_idx) { return 0; } @@ -431,6 +439,10 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElem= ent *elem, return; } =20 + if (unlikely(!vq->vring.used)) { + return; + } + idx =3D (idx + vq->used_idx) % vq->vring.num; =20 uelem.id =3D elem->index; @@ -448,6 +460,10 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count) return; } =20 + if (unlikely(!vq->vring.used)) { + return; + } + /* Make sure buffer is written before we update index. */ smp_wmb(); trace_virtqueue_flush(vq, count); @@ -546,6 +562,16 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned= int *in_bytes, int64_t len =3D 0; int rc; =20 + if (unlikely(!vq->vring.desc)) { + if (in_bytes) { + *in_bytes =3D 0; + } + if (out_bytes) { + *out_bytes =3D 0; + } + return; + } + rcu_read_lock(); idx =3D vq->last_avail_idx; total_bufs =3D in_total =3D out_total =3D 0; --=20 2.7.4 From nobody Sun May 5 16:41:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489578675930414.0293414411632; Wed, 15 Mar 2017 04:51:15 -0700 (PDT) Received: from localhost ([::1]:36316 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7SU-0007tN-Gp for importer@patchew.org; Wed, 15 Mar 2017 07:51:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37073) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7QD-0006ho-Fr for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1co7Q9-0003sc-Fj for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40534) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1co7Q9-0003s8-6t for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:49 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (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 31D0380F8E; Wed, 15 Mar 2017 11:48:49 +0000 (UTC) Received: from jason-ThinkPad-T450s.redhat.com (vpn1-6-37.pek2.redhat.com [10.72.6.37]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2FBmaXC031920; Wed, 15 Mar 2017 07:48:45 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 31D0380F8E Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jasowang@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 31D0380F8E From: Jason Wang To: mst@redhat.com, qemu-devel@nongnu.org Date: Wed, 15 Mar 2017 19:48:31 +0800 Message-Id: <1489578512-14031-3-git-send-email-jasowang@redhat.com> In-Reply-To: <1489578512-14031-1-git-send-email-jasowang@redhat.com> References: <1489578512-14031-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 15 Mar 2017 11:48:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH V4 2/3] virtio: destroy region cache during reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cornelia Huck , Paolo Bonzini , Jason Wang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We don't destroy region cache during reset which can make the maps of previous driver leaked to a buggy or malicious driver that don't set vring address before starting to use the device. Fix this by destroy the region cache during reset and validate it before trying to see them. Cc: Cornelia Huck Cc: Paolo Bonzini Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- Changes from V3: - remove unrelated whitespace change Changes from V2: - introduce a helper and assert caches !=3D NULL Changes from v1: - switch to use rcu in virtio_virtqueue_region_cache() - use unlikely() when needed --- hw/virtio/virtio.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 9164579..a00380f 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -185,10 +185,16 @@ static void vring_desc_read(VirtIODevice *vdev, VRing= Desc *desc, virtio_tswap16s(vdev, &desc->next); } =20 +static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *= vq) +{ + VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + assert(caches !=3D NULL); + return caches; +} /* Called within rcu_read_lock(). */ static inline uint16_t vring_avail_flags(VirtQueue *vq) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingAvail, flags); return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa); } @@ -196,7 +202,7 @@ static inline uint16_t vring_avail_flags(VirtQueue *vq) /* Called within rcu_read_lock(). */ static inline uint16_t vring_avail_idx(VirtQueue *vq) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingAvail, idx); vq->shadow_avail_idx =3D virtio_lduw_phys_cached(vq->vdev, &caches->av= ail, pa); return vq->shadow_avail_idx; @@ -205,7 +211,7 @@ static inline uint16_t vring_avail_idx(VirtQueue *vq) /* Called within rcu_read_lock(). */ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingAvail, ring[i]); return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa); } @@ -220,7 +226,7 @@ static inline uint16_t vring_get_used_event(VirtQueue *= vq) static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem, int i) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingUsed, ring[i]); virtio_tswap32s(vq->vdev, &uelem->id); virtio_tswap32s(vq->vdev, &uelem->len); @@ -231,7 +237,7 @@ static inline void vring_used_write(VirtQueue *vq, VRin= gUsedElem *uelem, /* Called within rcu_read_lock(). */ static uint16_t vring_used_idx(VirtQueue *vq) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingUsed, idx); return virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); } @@ -239,7 +245,7 @@ static uint16_t vring_used_idx(VirtQueue *vq) /* Called within rcu_read_lock(). */ static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); hwaddr pa =3D offsetof(VRingUsed, idx); virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val); address_space_cache_invalidate(&caches->used, pa, sizeof(val)); @@ -249,7 +255,7 @@ static inline void vring_used_idx_set(VirtQueue *vq, ui= nt16_t val) /* Called within rcu_read_lock(). */ static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); VirtIODevice *vdev =3D vq->vdev; hwaddr pa =3D offsetof(VRingUsed, flags); uint16_t flags =3D virtio_lduw_phys_cached(vq->vdev, &caches->used, pa= ); @@ -261,7 +267,7 @@ static inline void vring_used_flags_set_bit(VirtQueue *= vq, int mask) /* Called within rcu_read_lock(). */ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask) { - VRingMemoryRegionCaches *caches =3D atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches =3D vring_get_region_caches(vq); VirtIODevice *vdev =3D vq->vdev; hwaddr pa =3D offsetof(VRingUsed, flags); uint16_t flags =3D virtio_lduw_phys_cached(vq->vdev, &caches->used, pa= ); @@ -279,7 +285,7 @@ static inline void vring_set_avail_event(VirtQueue *vq,= uint16_t val) return; } =20 - caches =3D atomic_rcu_read(&vq->vring.caches); + caches =3D vring_get_region_caches(vq); pa =3D offsetof(VRingUsed, ring[vq->vring.num]); virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val); address_space_cache_invalidate(&caches->used, pa, sizeof(val)); @@ -577,7 +583,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned = int *in_bytes, total_bufs =3D in_total =3D out_total =3D 0; =20 max =3D vq->vring.num; - caches =3D atomic_rcu_read(&vq->vring.caches); + caches =3D vring_get_region_caches(vq); if (caches->desc.len < max * sizeof(VRingDesc)) { virtio_error(vdev, "Cannot map descriptor ring"); goto err; @@ -844,7 +850,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) =20 i =3D head; =20 - caches =3D atomic_rcu_read(&vq->vring.caches); + caches =3D vring_get_region_caches(vq); if (caches->desc.len < max * sizeof(VRingDesc)) { virtio_error(vdev, "Cannot map descriptor ring"); goto done; @@ -1143,6 +1149,17 @@ static enum virtio_device_endian virtio_current_cpu_= endian(void) } } =20 +static void virtio_virtqueue_reset_region_cache(struct VirtQueue *vq) +{ + VRingMemoryRegionCaches *caches; + + caches =3D atomic_read(&vq->vring.caches); + atomic_rcu_set(&vq->vring.caches, NULL); + if (caches) { + call_rcu(caches, virtio_free_region_cache, rcu); + } +} + void virtio_reset(void *opaque) { VirtIODevice *vdev =3D opaque; @@ -1183,6 +1200,7 @@ void virtio_reset(void *opaque) vdev->vq[i].notification =3D true; vdev->vq[i].vring.num =3D vdev->vq[i].vring.num_default; vdev->vq[i].inuse =3D 0; + virtio_virtqueue_reset_region_cache(&vdev->vq[i]); } } =20 @@ -2477,13 +2495,10 @@ static void virtio_device_free_virtqueues(VirtIODev= ice *vdev) } =20 for (i =3D 0; i < VIRTIO_QUEUE_MAX; i++) { - VRingMemoryRegionCaches *caches; if (vdev->vq[i].vring.num =3D=3D 0) { break; } - caches =3D atomic_read(&vdev->vq[i].vring.caches); - atomic_set(&vdev->vq[i].vring.caches, NULL); - virtio_free_region_cache(caches); + virtio_virtqueue_reset_region_cache(&vdev->vq[i]); } g_free(vdev->vq); } --=20 2.7.4 From nobody Sun May 5 16:41:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489578673922728.1844615194636; Wed, 15 Mar 2017 04:51:13 -0700 (PDT) Received: from localhost ([::1]:36314 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7SR-0007rN-9a for importer@patchew.org; Wed, 15 Mar 2017 07:51:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37082) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co7QE-0006ib-BO for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1co7QD-0003u3-Hc for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48294) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1co7QD-0003tq-8n for qemu-devel@nongnu.org; Wed, 15 Mar 2017 07:48:53 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (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 3BFE381241; Wed, 15 Mar 2017 11:48:53 +0000 (UTC) Received: from jason-ThinkPad-T450s.redhat.com (vpn1-6-37.pek2.redhat.com [10.72.6.37]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2FBmaXD031920; Wed, 15 Mar 2017 07:48:50 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3BFE381241 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jasowang@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3BFE381241 From: Jason Wang To: mst@redhat.com, qemu-devel@nongnu.org Date: Wed, 15 Mar 2017 19:48:32 +0800 Message-Id: <1489578512-14031-4-git-send-email-jasowang@redhat.com> In-Reply-To: <1489578512-14031-1-git-send-email-jasowang@redhat.com> References: <1489578512-14031-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 15 Mar 2017 11:48:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH V4 3/3] virtio: validate address space cache during init X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cornelia Huck , Paolo Bonzini , Jason Wang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We don't check the return value of address_space_cache_init(), this may lead buggy driver use incorrect region caches. Instead of triggering an assert, catch and warn this early in virtio_init_region_cache(). Cc: Cornelia Huck Cc: Paolo Bonzini Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- hw/virtio/virtio.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index a00380f..82b6060 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -131,6 +131,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev= , int n) VRingMemoryRegionCaches *new; hwaddr addr, size; int event_size; + int64_t len; =20 event_size =3D virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_I= DX) ? 2 : 0; =20 @@ -140,21 +141,41 @@ static void virtio_init_region_cache(VirtIODevice *vd= ev, int n) } new =3D g_new0(VRingMemoryRegionCaches, 1); size =3D virtio_queue_get_desc_size(vdev, n); - address_space_cache_init(&new->desc, vdev->dma_as, - addr, size, false); + len =3D address_space_cache_init(&new->desc, vdev->dma_as, + addr, size, false); + if (len < size) { + virtio_error(vdev, "Cannot map desc"); + goto err_desc; + } =20 size =3D virtio_queue_get_used_size(vdev, n) + event_size; - address_space_cache_init(&new->used, vdev->dma_as, - vq->vring.used, size, true); + len =3D address_space_cache_init(&new->used, vdev->dma_as, + vq->vring.used, size, true); + if (len < size) { + virtio_error(vdev, "Cannot map used"); + goto err_used; + } =20 size =3D virtio_queue_get_avail_size(vdev, n) + event_size; - address_space_cache_init(&new->avail, vdev->dma_as, - vq->vring.avail, size, false); + len =3D address_space_cache_init(&new->avail, vdev->dma_as, + vq->vring.avail, size, false); + if (len < size) { + virtio_error(vdev, "Cannot map avail"); + goto err_avail; + } =20 atomic_rcu_set(&vq->vring.caches, new); if (old) { call_rcu(old, virtio_free_region_cache, rcu); } + return; + +err_avail: + address_space_cache_destroy(&new->used); +err_used: + address_space_cache_destroy(&new->desc); +err_desc: + g_free(new); } =20 /* virt queue functions */ --=20 2.7.4