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:
parent
aca01ae87e
commit
9e16c84fbf
74
hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch
Normal file
74
hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From 95970127dcd1d5d2f365f87fa888e5f0baa3cd10 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 | 23 +++++++++++++++++++----
|
||||||
|
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
|
||||||
|
index 47fb79aa4d..ac02548dcf 100644
|
||||||
|
--- a/hw/usb/hcd-xhci.c
|
||||||
|
+++ b/hw/usb/hcd-xhci.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/timer.h"
|
||||||
|
+#include "qemu/log.h"
|
||||||
|
#include "qemu/module.h"
|
||||||
|
#include "qemu/queue.h"
|
||||||
|
#include "migration/vmstate.h"
|
||||||
|
@@ -726,10 +727,14 @@ 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;
|
||||||
|
- dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE,
|
||||||
|
- MEMTXATTRS_UNSPECIFIED);
|
||||||
|
+ if (dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE,
|
||||||
|
+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||||
|
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||||
|
+ __func__);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
le64_to_cpus(&trb.parameter);
|
||||||
|
le32_to_cpus(&trb.status);
|
||||||
|
le32_to_cpus(&trb.control);
|
||||||
|
@@ -763,7 +768,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
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: qemu
|
Name: qemu
|
||||||
Version: 6.2.0
|
Version: 6.2.0
|
||||||
Release: 48
|
Release: 49
|
||||||
Epoch: 10
|
Epoch: 10
|
||||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||||
@ -303,6 +303,7 @@ Patch0289: hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch
|
|||||||
Patch0291: tests-qtest-Add-fuzz-lsi53c895a-test.patch
|
Patch0291: tests-qtest-Add-fuzz-lsi53c895a-test.patch
|
||||||
Patch0292: scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch
|
Patch0292: scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch
|
||||||
Patch0293: scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch
|
Patch0293: scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch
|
||||||
|
Patch0294: hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch
|
||||||
|
|
||||||
BuildRequires: flex
|
BuildRequires: flex
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
@ -815,6 +816,9 @@ getent passwd qemu >/dev/null || \
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Sep 03 2022 yezengruan <yezengruan@huawei.com> - 10:6.2.0-49
|
||||||
|
- hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() (CVE-2020-14394)
|
||||||
|
|
||||||
* Tue Aug 30 2022 yezengruan <yezengruan@huawei.com> - 10:6.2.0-48
|
* Tue Aug 30 2022 yezengruan <yezengruan@huawei.com> - 10:6.2.0-48
|
||||||
- hw/scsi/lsi53c895a: Do not abort when DMA requested and no data queued
|
- hw/scsi/lsi53c895a: Do not abort when DMA requested and no data queued
|
||||||
- tests/qtest: Add fuzz-lsi53c895a-test
|
- tests/qtest: Add fuzz-lsi53c895a-test
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user