From nobody Sat Apr 27 06:23:08 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1660754079; cv=none; d=zohomail.com; s=zohoarc; b=hxhwZHoOZpS9pM8DsPgm+VwVbYokggweIs3t3GMY7wplgFxvY8PP3GB5nzff3Mcx7Sa+obfl+6ADyEuQfXQ2RdvKVULJRWsd2Xfb607+i2ycZmrLWdmqwUk5b9RBIxKB5wyoufqC2IgbM40GywI6DjZGtq4Gx9KsdRLcPaZxj1s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1660754079; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=H43lzbRGPP4EOoexD98MPnpxMlgiqilN7AJEFK0GAg0=; b=KKVynIRxTcFXA+pDcgSn7eoWD2cTOix0aa48/2gw227PGFDAEF1RTl+2N8bmItaJ9LYLJEjnz9mIaXfsg5+GC9QT9WKW2frealwJia4ZErmh6K5yKus4wL3aVBsIC0s/oDbIVEKaGk3uljvWZToTkbM5KxqOHFbpd74RpreD7q8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1660754079946739.8326419138872; Wed, 17 Aug 2022 09:34:39 -0700 (PDT) Received: from localhost ([::1]:46952 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oOM06-0006AD-TB for importer2@patchew.org; Wed, 17 Aug 2022 12:34:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53594) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oOLTE-0000ZJ-A7 for qemu-devel@nongnu.org; Wed, 17 Aug 2022 12:00:40 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22311) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oOLT9-0002qv-Hw for qemu-devel@nongnu.org; Wed, 17 Aug 2022 12:00:38 -0400 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-248-agvi6s8BPZCEQjDg83jprQ-1; Wed, 17 Aug 2022 12:00:31 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 85CF21857F1D for ; Wed, 17 Aug 2022 16:00:21 +0000 (UTC) Received: from thuth.com (unknown [10.39.193.186]) by smtp.corp.redhat.com (Postfix) with ESMTP id 871D7400E122; Wed, 17 Aug 2022 16:00:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1660752033; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=H43lzbRGPP4EOoexD98MPnpxMlgiqilN7AJEFK0GAg0=; b=WSkgIdejXdCc6VxuTkwli9Dh9CXWcwzllFW0TI/kQRvonfVwWH19/rAAlyTlC6eTXqpPfU xPIRANkclAmsK6LoGfuCm61V+Wl4ddzHhVFTKKXGXFWTNjXXggFAEktNvgfFmbaTA/iLuq hZ+8yuo31BP1Y+lmCGK3fGqD4gQSU2g= X-MC-Unique: agvi6s8BPZCEQjDg83jprQ-1 From: Thomas Huth To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Subject: [PATCH for-7.2] hw/usb/hcd-xhci: Check whether DMA accesses fail Date: Wed, 17 Aug 2022 18:00:16 +0200 Message-Id: <20220817160016.49752-1-thuth@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1660754080742100001 Content-Type: text/plain; charset="utf-8" If a guest sets up bad descriptors, it could force QEMU to access non-existing memory regions. Thus we should check the return value of dma_memory_read/write() to make sure that these errors don't go unnoticed. Signed-off-by: Thomas Huth --- hw/usb/hcd-xhci.c | 64 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 3c48b58dde..acd60b1a49 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -463,6 +463,12 @@ static void xhci_mfwrap_timer(void *opaque) xhci_mfwrap_update(xhci); } =20 +static void xhci_die(XHCIState *xhci) +{ + xhci->usbsts |=3D USBSTS_HCE; + DPRINTF("xhci: asserted controller error\n"); +} + static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high) { if (sizeof(dma_addr_t) =3D=3D 4) { @@ -488,7 +494,14 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci,= dma_addr_t addr, =20 assert((len % sizeof(uint32_t)) =3D=3D 0); =20 - dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED); + if (dma_memory_read(xhci->as, addr, buf, len, + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", + __func__); + memset(buf, 0xff, len); + xhci_die(xhci); + return; + } =20 for (i =3D 0; i < (len / sizeof(uint32_t)); i++) { buf[i] =3D le32_to_cpu(buf[i]); @@ -496,7 +509,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, = dma_addr_t addr, } =20 static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr, - uint32_t *buf, size_t len) + const uint32_t *buf, size_t len) { int i; uint32_t tmp[5]; @@ -508,7 +521,13 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci= , dma_addr_t addr, for (i =3D 0; i < n; i++) { tmp[i] =3D cpu_to_le32(buf[i]); } - dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED); + if (dma_memory_write(xhci->as, addr, tmp, len, + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", + __func__); + xhci_die(xhci); + return; + } } =20 static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) @@ -593,12 +612,6 @@ static inline int xhci_running(XHCIState *xhci) return !(xhci->usbsts & USBSTS_HCH); } =20 -static void xhci_die(XHCIState *xhci) -{ - xhci->usbsts |=3D USBSTS_HCE; - DPRINTF("xhci: asserted controller error\n"); -} - static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v) { XHCIInterrupter *intr =3D &xhci->intr[v]; @@ -619,7 +632,12 @@ static void xhci_write_event(XHCIState *xhci, XHCIEven= t *event, int v) ev_trb.status, ev_trb.control); =20 addr =3D intr->er_start + TRB_SIZE*intr->er_ep_idx; - dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, MEMTXATTRS_UNSPECI= FIED); + if (dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", + __func__); + xhci_die(xhci); + } =20 intr->er_ep_idx++; if (intr->er_ep_idx >=3D intr->er_size) { @@ -680,8 +698,12 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRi= ng *ring, XHCITRB *trb, =20 while (1) { TRBType type; - dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE, - MEMTXATTRS_UNSPECIFIED); + if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE, + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\= n", + __func__); + return 0; + } trb->addr =3D ring->dequeue; trb->ccs =3D ring->ccs; le64_to_cpus(&trb->parameter); @@ -798,8 +820,14 @@ static void xhci_er_reset(XHCIState *xhci, int v) xhci_die(xhci); return; } - dma_memory_read(xhci->as, erstba, &seg, sizeof(seg), - MEMTXATTRS_UNSPECIFIED); + if (dma_memory_read(xhci->as, erstba, &seg, sizeof(seg), + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", + __func__); + xhci_die(xhci); + return; + } + le32_to_cpus(&seg.addr_low); le32_to_cpus(&seg.addr_high); le32_to_cpus(&seg.size); @@ -2415,8 +2443,12 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *x= hci, uint64_t pctx) /* TODO: actually implement real values here */ bw_ctx[0] =3D 0; memset(&bw_ctx[1], 80, xhci->numports); /* 80% */ - dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx), - MEMTXATTRS_UNSPECIFIED); + if (dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx), + MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory write failed!\n", + __func__); + return CC_TRB_ERROR; + } =20 return CC_SUCCESS; } --=20 2.31.1