From bf46d59f2872133f7d432640da053dd000727b1e Mon Sep 17 00:00:00 2001 From: yezengruan Date: Sat, 3 Sep 2022 09:17:16 +0800 Subject: [PATCH] hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() (CVE-2020-14394) Signed-off-by: yezengruan (cherry picked from commit 9e16c84fbf0f5f14fcf086e2eea666f667a95385) --- ...Fix-unbounded-loop-in-xhci_ring_chai.patch | 74 +++++++++++++++++++ qemu.spec | 6 +- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch diff --git a/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch b/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch new file mode 100644 index 0000000..2caeb1c --- /dev/null +++ b/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch @@ -0,0 +1,74 @@ +From 95970127dcd1d5d2f365f87fa888e5f0baa3cd10 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +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 +Acked-by: Gerd Hoffmann +Signed-off-by: Thomas Huth +--- + 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 + diff --git a/qemu.spec b/qemu.spec index 2e4808d..89718ef 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 48 +Release: 49 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 @@ -303,6 +303,7 @@ Patch0289: hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch Patch0291: tests-qtest-Add-fuzz-lsi53c895a-test.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 +Patch0294: hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch BuildRequires: flex BuildRequires: gcc @@ -815,6 +816,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Sep 03 2022 yezengruan - 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 - 10:6.2.0-48 - hw/scsi/lsi53c895a: Do not abort when DMA requested and no data queued - tests/qtest: Add fuzz-lsi53c895a-test -- Gitee