summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch')
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch79
1 files changed, 79 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch
new file mode 100644
index 0000000000..aff91a7355
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-14394.patch
@@ -0,0 +1,79 @@
+From effaf5a240e03020f4ae953e10b764622c3e87cc Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 8 Aug 2023 10:44:51 +0000
+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>
+
+CVE: CVE-2020-14394
+
+Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/effaf5a240e03020f4ae953e10b764622c3e87cc]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.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 14bdb8967..c63a36dcc 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"
+@@ -725,10 +726,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);
+@@ -762,7 +767,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.35.5