From 77a5b2b9137c382b5facb6a42818fa621b917c61 Mon Sep 17 00:00:00 2001 From: liningjie Date: Tue, 17 Oct 2023 14:56:41 +0800 Subject: [PATCH] Fix CVE-2023-0330 --- backport-CVE-2023-0330.patch | 124 +++++++++++++++++++++++++++++++++++ qemu.spec | 6 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2023-0330.patch diff --git a/backport-CVE-2023-0330.patch b/backport-CVE-2023-0330.patch new file mode 100644 index 0000000..46d6d04 --- /dev/null +++ b/backport-CVE-2023-0330.patch @@ -0,0 +1,124 @@ +From 62b5107d16ee5b46daae111f0868163f20ea7c69 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Tue, 17 Oct 2023 11:59:11 +0800 +Subject: [PATCH] hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI + controller (CVE-2023-0330) + +We cannot use the generic reentrancy guard in the LSI code, so +we have to manually prevent endless reentrancy here. The problematic +lsi_execute_script() function has already a way to detect whether +too many instructions have been executed - we just have to slightly +change the logic here that it also takes into account if the function +has been called too often in a reentrant way. + +The code in fuzz-lsi53c895a-test.c has been taken from an earlier +patch by Mauro Matteo Cascella. + +Resolves: #1563 + +Message-Id: <20230522091011.1082574-1-thuth@redhat.com> +Reviewed-by: Stefan Hajnoczi's avatarStefan Hajnoczi +Reviewed-by: default avatarAlexander Bulekov +Signed-off-by: Thomas Huth's avatarThomas Huth +--- + hw/scsi/lsi53c895a.c | 23 +++++++++++++++------ + tests/qtest/fuzz-lsi53c895a-test.c | 32 ++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+), 6 deletions(-) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index b9c9eb0da..f7559051c 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -1134,15 +1134,24 @@ static void lsi_execute_script(LSIState *s) + uint32_t addr, addr_high; + int opcode; + int insn_processed = 0; ++ static int reentrancy_level; ++ ++ reentrancy_level++; + + s->istat1 |= LSI_ISTAT1_SRUN; + again: +- if (++insn_processed > LSI_MAX_INSN) { +- /* Some windows drivers make the device spin waiting for a memory +- location to change. If we have been executed a lot of code then +- assume this is the case and force an unexpected device disconnect. +- This is apparently sufficient to beat the drivers into submission. +- */ ++ /* ++ * Some windows drivers make the device spin waiting for a memory location ++ * to change. If we have executed more than LSI_MAX_INSN instructions then ++ * assume this is the case and force an unexpected device disconnect. This ++ * is apparently sufficient to beat the drivers into submission. ++ * ++ * Another issue (CVE-2023-0330) can occur if the script is programmed to ++ * trigger itself again and again. Avoid this problem by stopping after ++ * being called multiple times in a reentrant way (8 is an arbitrary value ++ * which should be enough for all valid use cases). ++ */ ++ if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) { + if (!(s->sien0 & LSI_SIST0_UDC)) { + qemu_log_mask(LOG_GUEST_ERROR, + "lsi_scsi: inf. loop with UDC masked"); +@@ -1596,6 +1605,8 @@ again: + } + } + trace_lsi_execute_script_stop(); ++ ++ reentrancy_level--; + } + + static uint8_t lsi_reg_readb(LSIState *s, int offset) +diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c +index 0f968024c..1a33b555e 100644 +--- a/tests/qtest/fuzz-lsi53c895a-test.c ++++ b/tests/qtest/fuzz-lsi53c895a-test.c +@@ -8,6 +8,36 @@ + #include "qemu/osdep.h" + #include "libqos/libqtest.h" + ++/* ++ * This used to trigger a DMA reentrancy issue ++ * leading to memory corruption bugs like stack ++ * overflow or use-after-free ++ * https://gitlab.com/qemu-project/qemu/-/issues/1563 ++ */ ++static void test_lsi_dma_reentrancy(void) ++{ ++ QTestState *s; ++ ++ s = qtest_init("-M q35 -m 512M -nodefaults " ++ "-blockdev driver=null-co,node-name=null0 " ++ "-device lsi53c810 -device scsi-cd,drive=null0"); ++ ++ qtest_outl(s, 0xcf8, 0x80000804); /* PCI Command Register */ ++ qtest_outw(s, 0xcfc, 0x7); /* Enables accesses */ ++ qtest_outl(s, 0xcf8, 0x80000814); /* Memory Bar 1 */ ++ qtest_outl(s, 0xcfc, 0xff100000); /* Set MMIO Address*/ ++ qtest_outl(s, 0xcf8, 0x80000818); /* Memory Bar 2 */ ++ qtest_outl(s, 0xcfc, 0xff000000); /* Set RAM Address*/ ++ qtest_writel(s, 0xff000000, 0xc0000024); ++ qtest_writel(s, 0xff000114, 0x00000080); ++ qtest_writel(s, 0xff00012c, 0xff000000); ++ qtest_writel(s, 0xff000004, 0xff000114); ++ qtest_writel(s, 0xff000008, 0xff100014); ++ qtest_writel(s, 0xff10002f, 0x000000ff); ++ ++ qtest_quit(s); ++} ++ + /* + * This used to trigger a UAF in lsi_do_msgout() + * https://gitlab.com/qemu-project/qemu/-/issues/972 +@@ -121,6 +151,8 @@ int main(int argc, char **argv) + test_lsi_do_dma_empty_queue); + qtest_add_func("fuzz/lsi53c895a/lsi_do_msgout_cancel_req", + test_lsi_do_msgout_cancel_req); ++ qtest_add_func("fuzz/lsi53c895a/lsi_dma_reentrancy", ++ test_lsi_dma_reentrancy); + } + + return g_test_run(); +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 18fc734..9e1d07a 100644 --- a/qemu.spec +++ b/qemu.spec @@ -4,7 +4,7 @@ Name: qemu Version: 6.2.0 Release: 80 -Epoch: 10 +Epoch: 11 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 URL: http://www.qemu.org @@ -565,6 +565,7 @@ Patch0550: vhost-Drop-unused-eventfd_add-del-hooks.patch Patch0551: chardev-report-the-handshake-error.patch Patch0552: hw-ssi-Fix-Linux-driver-init-issue-with-xilinx_spi.patch Patch0553: io-remove-io-watch-if-TLS-channel-is-closed-during-h.patch +Patch0554: backport-CVE-2023-0330.patch BuildRequires: flex BuildRequires: gcc @@ -1138,6 +1139,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Tue Oct 17 2023 - 10:6.2.0-81 +- Fix CVE-2023-0330 + * Sat Sep 9 2023 - 10:6.2.0-80 - io: remove io watch if TLS channel is closed during handshake - hw/ssi: Fix Linux driver init issue with xilinx_spi -- Gitee