diff --git a/block-nvme-Fix-VFIO_MAP_DMA-failed-No-sp.patch b/block-nvme-Fix-VFIO_MAP_DMA-failed-No-sp.patch new file mode 100644 index 00000000..12a7de6e --- /dev/null +++ b/block-nvme-Fix-VFIO_MAP_DMA-failed-No-sp.patch @@ -0,0 +1,92 @@ +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Fri, 23 Jul 2021 21:58:43 +0200 +Subject: block/nvme: Fix VFIO_MAP_DMA failed: No space left on device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 15a730e7a3aaac180df72cd5730e0617bcf44a5a + +When the NVMe block driver was introduced (see commit bdd6a90a9e5, +January 2018), Linux VFIO_IOMMU_MAP_DMA ioctl was only returning +-ENOMEM in case of error. The driver was correctly handling the +error path to recycle its volatile IOVA mappings. + +To fix CVE-2019-3882, Linux commit 492855939bdb ("vfio/type1: Limit +DMA mappings per container", April 2019) added the -ENOSPC error to +signal the user exhausted the DMA mappings available for a container. + +The block driver started to mis-behave: + + qemu-system-x86_64: VFIO_MAP_DMA failed: No space left on device + (qemu) + (qemu) info status + VM status: paused (io-error) + (qemu) c + VFIO_MAP_DMA failed: No space left on device + (qemu) c + VFIO_MAP_DMA failed: No space left on device + +(The VM is not resumable from here, hence stuck.) + +Fix by handling the new -ENOSPC error (when DMA mappings are +exhausted) without any distinction to the current -ENOMEM error, +so we don't change the behavior on old kernels where the CVE-2019-3882 +fix is not present. + +An easy way to reproduce this bug is to restrict the DMA mapping +limit (65535 by default) when loading the VFIO IOMMU module: + + # modprobe vfio_iommu_type1 dma_entry_limit=666 + +Cc: qemu-stable@nongnu.org +Cc: Fam Zheng +Cc: Maxim Levitsky +Cc: Alex Williamson +Reported-by: Michal Prívozník +Signed-off-by: Philippe Mathieu-Daudé +Message-id: 20210723195843.1032825-1-philmd@redhat.com +Fixes: bdd6a90a9e5 ("block: Add VFIO based NVMe driver") +Buglink: https://bugs.launchpad.net/qemu/+bug/1863333 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/65 +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Jose R. Ziviani +--- + block/nvme.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/block/nvme.c b/block/nvme.c +index 2b5421e7aa6e0a3bfaf403203c9b..e8dbbc23177d8e89d67349fc15a8 100644 +--- a/block/nvme.c ++++ b/block/nvme.c +@@ -1030,7 +1030,29 @@ try_map: + r = qemu_vfio_dma_map(s->vfio, + qiov->iov[i].iov_base, + len, true, &iova); ++ if (r == -ENOSPC) { ++ /* ++ * In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA ++ * ioctl returns -ENOSPC to signal the user exhausted the DMA ++ * mappings available for a container since Linux kernel commit ++ * 492855939bdb ("vfio/type1: Limit DMA mappings per container", ++ * April 2019, see CVE-2019-3882). ++ * ++ * This block driver already handles this error path by checking ++ * for the -ENOMEM error, so we directly replace -ENOSPC by ++ * -ENOMEM. Beside, -ENOSPC has a specific meaning for blockdev ++ * coroutines: it triggers BLOCKDEV_ON_ERROR_ENOSPC and ++ * BLOCK_ERROR_ACTION_STOP which stops the VM, asking the operator ++ * to add more storage to the blockdev. Not something we can do ++ * easily with an IOMMU :) ++ */ ++ r = -ENOMEM; ++ } + if (r == -ENOMEM && retry) { ++ /* ++ * We exhausted the DMA mappings available for our container: ++ * recycle the volatile IOVA mappings. ++ */ + retry = false; + trace_nvme_dma_flush_queue_wait(s); + if (s->dma_map_count) { diff --git a/bundles.tar.xz b/bundles.tar.xz index 4206e03a..b83a5a8a 100644 --- a/bundles.tar.xz +++ b/bundles.tar.xz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ec63ad5df6ad6e4aa0b206d4db157c88cf8ae8bfd8261a7332f7c6a1f24cab8 -size 75016 +oid sha256:f01e2ec49bb5088e9e97f58d8fc422acb6760c387e1313e49a4d13979a5b48c8 +size 77828 diff --git a/hw-net-can-sja1000-fix-buff2frame_bas-an.patch b/hw-net-can-sja1000-fix-buff2frame_bas-an.patch new file mode 100644 index 00000000..0fc2e197 --- /dev/null +++ b/hw-net-can-sja1000-fix-buff2frame_bas-an.patch @@ -0,0 +1,51 @@ +From: Pavel Pisa +Date: Thu, 29 Jul 2021 14:33:27 +0200 +Subject: hw/net/can: sja1000 fix buff2frame_bas and buff2frame_pel when dlc is + out of std CAN 8 bytes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 11744862f27b9ba6488a247d2fd6bb83d9bc3c8d + +Problem reported by openEuler fuzz-sig group. + +The buff2frame_bas function (hw\net\can\can_sja1000.c) +infoleak(qemu5.x~qemu6.x) or stack-overflow(qemu 4.x). + +Reported-by: Qiang Ning +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Pavel Pisa +Signed-off-by: Jason Wang +Signed-off-by: Jose R. Ziviani +--- + hw/net/can/can_sja1000.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c +index 42d2f99dfb1d3cd3fa26f56ccb8d..34eea684ced278738bdb26327100 100644 +--- a/hw/net/can/can_sja1000.c ++++ b/hw/net/can/can_sja1000.c +@@ -275,6 +275,10 @@ static void buff2frame_pel(const uint8_t *buff, qemu_can_frame *frame) + } + frame->can_dlc = buff[0] & 0x0f; + ++ if (frame->can_dlc > 8) { ++ frame->can_dlc = 8; ++ } ++ + if (buff[0] & 0x80) { /* Extended */ + frame->can_id |= QEMU_CAN_EFF_FLAG; + frame->can_id |= buff[1] << 21; /* ID.28~ID.21 */ +@@ -311,6 +315,10 @@ static void buff2frame_bas(const uint8_t *buff, qemu_can_frame *frame) + } + frame->can_dlc = buff[1] & 0x0f; + ++ if (frame->can_dlc > 8) { ++ frame->can_dlc = 8; ++ } ++ + for (i = 0; i < frame->can_dlc; i++) { + frame->data[i] = buff[2 + i]; + } diff --git a/hw-pci-host-q35-Ignore-write-of-reserved.patch b/hw-pci-host-q35-Ignore-write-of-reserved.patch new file mode 100644 index 00000000..3b0c52ed --- /dev/null +++ b/hw-pci-host-q35-Ignore-write-of-reserved.patch @@ -0,0 +1,71 @@ +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Wed, 26 May 2021 16:24:38 +0200 +Subject: hw/pci-host/q35: Ignore write of reserved PCIEXBAR LENGTH field +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 9b0ca75e0196a72523232063db1e07ae36a5077a + +libFuzzer triggered the following assertion: + + cat << EOF | qemu-system-i386 -M pc-q35-5.0 \ + -nographic -monitor none -serial none \ + -qtest stdio -d guest_errors -trace pci\* + outl 0xcf8 0xf2000060 + outl 0xcfc 0x8400056e + EOF + pci_cfg_write mch 00:0 @0x60 <- 0x8400056e + Aborted (core dumped) + +This is because guest wrote MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD +(reserved value) to the PCIE XBAR register. + +There is no indication on the datasheet about what occurs when +this value is written. Simply ignore it on QEMU (and report an +guest error): + + pci_cfg_write mch 00:0 @0x60 <- 0x8400056e + Q35: Reserved PCIEXBAR LENGTH + pci_cfg_read mch 00:0 @0x0 -> 0x8086 + pci_cfg_read mch 00:0 @0x0 -> 0x29c08086 + ... + +Cc: qemu-stable@nongnu.org +Reported-by: Alexander Bulekov +BugLink: https://bugs.launchpad.net/qemu/+bug/1878641 +Fixes: df2d8b3ed4 ("q35: Introduce q35 pc based chipset emulator") +Reviewed-by: Richard Henderson +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20210526142438.281477-1-f4bug@amsat.org> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Alexander Bulekov +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Jose R. Ziviani +--- + hw/pci-host/q35.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c +index 2eb729dff5854aff586d9ac813f9..0f37cf056a9af4081f2350400ab2 100644 +--- a/hw/pci-host/q35.c ++++ b/hw/pci-host/q35.c +@@ -29,6 +29,7 @@ + */ + + #include "qemu/osdep.h" ++#include "qemu/log.h" + #include "hw/i386/pc.h" + #include "hw/pci-host/q35.h" + #include "hw/qdev-properties.h" +@@ -318,6 +319,8 @@ static void mch_update_pciexbar(MCHPCIState *mch) + addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK; + break; + case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD: ++ qemu_log_mask(LOG_GUEST_ERROR, "Q35: Reserved PCIEXBAR LENGTH\n"); ++ return; + default: + abort(); + } diff --git a/qemu.changes b/qemu.changes index 6a1d2623..938d0bb0 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Aug 3 20:39:25 UTC 2021 - José Ricardo Ziviani + +- Add stable patches from upstream: + block-nvme-Fix-VFIO_MAP_DMA-failed-No-sp.patch + hw-net-can-sja1000-fix-buff2frame_bas-an.patch + hw-pci-host-q35-Ignore-write-of-reserved.patch + ------------------------------------------------------------------- Fri Jul 23 19:43:33 UTC 2021 - José Ricardo Ziviani diff --git a/qemu.spec b/qemu.spec index 576f7366..36e6154a 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,5 +1,5 @@ # -# spec file +# spec file for package qemu # # Copyright (c) 2021 SUSE LLC # @@ -223,6 +223,9 @@ Patch00087: hw-nvme-fix-pin-based-interrupt-behavior.patch Patch00088: hw-rdma-Fix-possible-mremap-overflow-in-.patch Patch00089: pvrdma-Ensure-correct-input-on-ring-init.patch Patch00090: pvrdma-Fix-the-ring-init-error-flow-CVE-.patch +Patch00091: hw-pci-host-q35-Ignore-write-of-reserved.patch +Patch00092: block-nvme-Fix-VFIO_MAP_DMA-failed-No-sp.patch +Patch00093: hw-net-can-sja1000-fix-buff2frame_bas-an.patch # Patches applied in roms/seabios/: Patch01000: seabios-use-python2-explicitly-as-needed.patch Patch01001: seabios-switch-to-python3-as-needed.patch @@ -1159,6 +1162,9 @@ This package records qemu testsuite results and represents successful testing. %patch00088 -p1 %patch00089 -p1 %patch00090 -p1 +%patch00091 -p1 +%patch00092 -p1 +%patch00093 -p1 %patch01000 -p1 %patch01001 -p1 %patch01002 -p1