hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() (CVE-2020-14394)

Signed-off-by: yezengruan <yezengruan@huawei.com>
This commit is contained in:
yezengruan 2022-09-07 17:21:55 +08:00
parent 800d793fa7
commit dd421f155f
2 changed files with 70 additions and 1 deletions

View File

@ -0,0 +1,65 @@
From 61743ee9276c4ec9c3fb99d5b63b5ddf4eaae8fe Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Thu, 4 Aug 2022 15:13:00 +0200
Subject: [PATCH] hw/usb/hcd-xhci: Fix unbounded loop in
xhci_ring_chain_length() (CVE-2020-14394)
The loop condition in xhci_ring_chain_length() is under control of
the guest, and additionally the code does not check for failed DMA
transfers (e.g. if reaching the end of the RAM), so the loop there
could run for a very long time or even forever. Fix it by checking
the return value of dma_memory_read() and by introducing a maximum
loop length.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/646
Message-Id: <20220804131300.96368-1-thuth@redhat.com>
Reviewed-by: Mauro Matteo Cascella <mcascell@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/usb/hcd-xhci.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 3b25abcacd..7a318eb967 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -22,6 +22,7 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "qemu/timer.h"
+#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/queue.h"
#include "hw/usb.h"
@@ -770,7 +771,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
bool control_td_set = 0;
uint32_t link_cnt = 0;
- while (1) {
+ do {
TRBType type;
pci_dma_read(pci_dev, dequeue, &trb, TRB_SIZE);
le64_to_cpus(&trb.parameter);
@@ -806,7 +807,17 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
if (!control_td_set && !(trb.control & TRB_TR_CH)) {
return length;
}
- }
+
+ /*
+ * According to the xHCI spec, Transfer Ring segments should have
+ * a maximum size of 64 kB (see chapter "6 Data Structures")
+ */
+ } while (length < TRB_LINK_LIMIT * 65536 / TRB_SIZE);
+
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum tranfer ring size!\n",
+ __func__);
+
+ return -1;
}
static void xhci_er_reset(XHCIState *xhci, int v)
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: qemu
Version: 4.1.0
Release: 73
Release: 74
Epoch: 10
Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -375,6 +375,7 @@ Patch0362: softmmu-Always-initialize-xlat-in-address_space_tran.patch
Patch0363: hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch
Patch0364: scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch
Patch0365: scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch
Patch0366: hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch
BuildRequires: flex
BuildRequires: bison
@ -775,6 +776,9 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
* Wed Sep 07 2022 yezengruan <yezengruan@huawei.com>
- hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() (CVE-2020-14394)
* Tue Aug 30 2022 yezengruan <yezengruan@huawei.com>
- hw/scsi/lsi53c895a: Do not abort when DMA requested and no data queued
- scsi/lsi53c895a: fix use-after-free in lsi_do_msgout (CVE-2022-0216)