From b39643dc6ee4fab61b1d840a1124cb407c7c0af1 Mon Sep 17 00:00:00 2001 From: yezengruan Date: Sat, 21 May 2022 14:42:27 +0800 Subject: [PATCH] fix CVE-2021-3750 (openeuler !293) hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR (CVE-2021-3750) softmmu/physmem: Simplify flatview_write and address_space_access_valid softmmu/physmem: Introduce MemTxAttrs::memory field and MEMTX_ACCESS_ERROR --- ...3-Check-for-MEMTX_OK-instead-of-MEMT.patch | 55 +++++++ qemu.spec | 10 +- ...Introduce-MemTxAttrs-memory-field-an.patch | 151 ++++++++++++++++++ ...Simplify-flatview_write-and-address_.patch | 60 +++++++ 4 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch create mode 100644 softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch create mode 100644 softmmu-physmem-Simplify-flatview_write-and-address_.patch diff --git a/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch b/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch new file mode 100644 index 0000000..cf1bd37 --- /dev/null +++ b/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch @@ -0,0 +1,55 @@ +From 5c3db1128c90e0fa2bec139de6022aea0ae2ad12 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Wed, 15 Dec 2021 19:24:19 +0100 +Subject: [PATCH 1/3] hw/intc/arm_gicv3: Check for !MEMTX_OK instead of + MEMTX_ERROR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Quoting Peter Maydell: + + "These MEMTX_* aren't from the memory transaction + API functions; they're just being used by gicd_readl() and + friends as a way to indicate a success/failure so that the + actual MemoryRegionOps read/write fns like gicv3_dist_read() + can log a guest error." + +We are going to introduce more MemTxResult bits, so it is +safer to check for !MEMTX_OK rather than MEMTX_ERROR. + +Reviewed-by: Peter Xu +Reviewed-by: David Hildenbrand +Reviewed-by: Peter Maydell +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Peter Maydell +--- + hw/intc/arm_gicv3_redist.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c +index c8ff3eca08..99b11ca5ee 100644 +--- a/hw/intc/arm_gicv3_redist.c ++++ b/hw/intc/arm_gicv3_redist.c +@@ -462,7 +462,7 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data, + break; + } + +- if (r == MEMTX_ERROR) { ++ if (r != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest read at offset " TARGET_FMT_plx + " size %u\n", __func__, offset, size); +@@ -521,7 +521,7 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, + break; + } + +- if (r == MEMTX_ERROR) { ++ if (r != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write at offset " TARGET_FMT_plx + " size %u\n", __func__, offset, size); +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index cafa139..e143fe8 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 34 +Release: 35 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -244,6 +244,9 @@ Patch0230: virtio-net-fix-map-leaking-on-error-during-receive.patch Patch0231: vfio-pci-Ascend710-change-to-bar2-quirk.patch Patch0232: display-qxl-render-fix-race-condition-in-qxl_cursor-.patch Patch0233: ui-cursor-fix-integer-overflow-in-cursor_alloc-CVE-2.patch +Patch0234: hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch +Patch0235: softmmu-physmem-Simplify-flatview_write-and-address_.patch +Patch0236: softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch BuildRequires: flex BuildRequires: gcc @@ -704,6 +707,11 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat May 21 2022 yezengruan - 2:6.2.0-35 +- hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR (CVE-2021-3750) +- softmmu/physmem: Simplify flatview_write and address_space_access_valid +- softmmu/physmem: Introduce MemTxAttrs::memory field and MEMTX_ACCESS_ERROR + * Tue May 10 2022 yezengruan - 2:6.2.0-34 - display/qxl-render: fix race condition in qxl_cursor (CVE-2021-4207) - ui/cursor: fix integer overflow in cursor_alloc (CVE-2021-4206) diff --git a/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch b/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch new file mode 100644 index 0000000..0d8e64d --- /dev/null +++ b/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch @@ -0,0 +1,151 @@ +From 96a6c8fa67298d52ccc27a0ac5bdddd6c42068cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Wed, 15 Dec 2021 19:24:21 +0100 +Subject: [PATCH 3/3] softmmu/physmem: Introduce MemTxAttrs::memory field and + MEMTX_ACCESS_ERROR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add the 'memory' bit to the memory attributes to restrict bus +controller accesses to memories. + +Introduce flatview_access_allowed() to check bus permission +before running any bus transaction. + +Have read/write accessors return MEMTX_ACCESS_ERROR if an access is +restricted. + +There is no change for the default case where 'memory' is not set. + +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20211215182421.418374-4-philmd@redhat.com> +Reviewed-by: Richard Henderson +Reviewed-by: Stefan Hajnoczi +[thuth: Replaced MEMTX_BUS_ERROR with MEMTX_ACCESS_ERROR, remove "inline"] +Signed-off-by: Thomas Huth +--- + include/exec/memattrs.h | 9 +++++++++ + softmmu/physmem.c | 44 +++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 51 insertions(+), 2 deletions(-) + +diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h +index 95f2d20d55..9fb98bc1ef 100644 +--- a/include/exec/memattrs.h ++++ b/include/exec/memattrs.h +@@ -35,6 +35,14 @@ typedef struct MemTxAttrs { + unsigned int secure:1; + /* Memory access is usermode (unprivileged) */ + unsigned int user:1; ++ /* ++ * Bus interconnect and peripherals can access anything (memories, ++ * devices) by default. By setting the 'memory' bit, bus transaction ++ * are restricted to "normal" memories (per the AMBA documentation) ++ * versus devices. Access to devices will be logged and rejected ++ * (see MEMTX_ACCESS_ERROR). ++ */ ++ unsigned int memory:1; + /* Requester ID (for MSI for example) */ + unsigned int requester_id:16; + /* Invert endianness for this page */ +@@ -66,6 +74,7 @@ typedef struct MemTxAttrs { + #define MEMTX_OK 0 + #define MEMTX_ERROR (1U << 0) /* device returned an error */ + #define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */ ++#define MEMTX_ACCESS_ERROR (1U << 2) /* access denied */ + typedef uint32_t MemTxResult; + + #endif +diff --git a/softmmu/physmem.c b/softmmu/physmem.c +index 049e7b1454..ae26f72909 100644 +--- a/softmmu/physmem.c ++++ b/softmmu/physmem.c +@@ -41,6 +41,7 @@ + #include "qemu/config-file.h" + #include "qemu/error-report.h" + #include "qemu/qemu-print.h" ++#include "qemu/log.h" + #include "exec/memory.h" + #include "exec/ioport.h" + #include "sysemu/dma.h" +@@ -2767,6 +2768,33 @@ static bool prepare_mmio_access(MemoryRegion *mr) + return release_lock; + } + ++/** ++ * flatview_access_allowed ++ * @mr: #MemoryRegion to be accessed ++ * @attrs: memory transaction attributes ++ * @addr: address within that memory region ++ * @len: the number of bytes to access ++ * ++ * Check if a memory transaction is allowed. ++ * ++ * Returns: true if transaction is allowed, false if denied. ++ */ ++static bool flatview_access_allowed(MemoryRegion *mr, MemTxAttrs attrs, ++ hwaddr addr, hwaddr len) ++{ ++ if (likely(!attrs.memory)) { ++ return true; ++ } ++ if (memory_region_is_ram(mr)) { ++ return true; ++ } ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "Invalid access to non-RAM device at " ++ "addr 0x%" HWADDR_PRIX ", size %" HWADDR_PRIu ", " ++ "region '%s'\n", addr, len, memory_region_name(mr)); ++ return false; ++} ++ + /* Called within RCU critical section. */ + static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, +@@ -2781,7 +2809,10 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, + const uint8_t *buf = ptr; + + for (;;) { +- if (!memory_access_is_direct(mr, true)) { ++ if (!flatview_access_allowed(mr, attrs, addr1, l)) { ++ result |= MEMTX_ACCESS_ERROR; ++ /* Keep going. */ ++ } else if (!memory_access_is_direct(mr, true)) { + release_lock |= prepare_mmio_access(mr); + l = memory_access_size(mr, l, addr1); + /* XXX: could force current_cpu to NULL to avoid +@@ -2826,6 +2857,9 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + + l = len; + mr = flatview_translate(fv, addr, &addr1, &l, true, attrs); ++ if (!flatview_access_allowed(mr, attrs, addr, len)) { ++ return MEMTX_ACCESS_ERROR; ++ } + return flatview_write_continue(fv, addr, attrs, buf, len, + addr1, l, mr); + } +@@ -2844,7 +2878,10 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, + + fuzz_dma_read_cb(addr, len, mr); + for (;;) { +- if (!memory_access_is_direct(mr, false)) { ++ if (!flatview_access_allowed(mr, attrs, addr1, l)) { ++ result |= MEMTX_ACCESS_ERROR; ++ /* Keep going. */ ++ } else if (!memory_access_is_direct(mr, false)) { + /* I/O case */ + release_lock |= prepare_mmio_access(mr); + l = memory_access_size(mr, l, addr1); +@@ -2887,6 +2924,9 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, + + l = len; + mr = flatview_translate(fv, addr, &addr1, &l, false, attrs); ++ if (!flatview_access_allowed(mr, attrs, addr, len)) { ++ return MEMTX_ACCESS_ERROR; ++ } + return flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); + } +-- +2.27.0 + diff --git a/softmmu-physmem-Simplify-flatview_write-and-address_.patch b/softmmu-physmem-Simplify-flatview_write-and-address_.patch new file mode 100644 index 0000000..833fa84 --- /dev/null +++ b/softmmu-physmem-Simplify-flatview_write-and-address_.patch @@ -0,0 +1,60 @@ +From 105c54fca54e73f17abe244b457872926e43f8a2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Wed, 15 Dec 2021 19:24:20 +0100 +Subject: [PATCH 2/3] softmmu/physmem: Simplify flatview_write and + address_space_access_valid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove unuseful local 'result' variables. + +Reviewed-by: Peter Xu +Reviewed-by: David Hildenbrand +Reviewed-by: Alexander Bulekov +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20211215182421.418374-3-philmd@redhat.com> +Signed-off-by: Thomas Huth +--- + softmmu/physmem.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/softmmu/physmem.c b/softmmu/physmem.c +index 3b9a61448c..049e7b1454 100644 +--- a/softmmu/physmem.c ++++ b/softmmu/physmem.c +@@ -2823,14 +2823,11 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + hwaddr l; + hwaddr addr1; + MemoryRegion *mr; +- MemTxResult result = MEMTX_OK; + + l = len; + mr = flatview_translate(fv, addr, &addr1, &l, true, attrs); +- result = flatview_write_continue(fv, addr, attrs, buf, len, +- addr1, l, mr); +- +- return result; ++ return flatview_write_continue(fv, addr, attrs, buf, len, ++ addr1, l, mr); + } + + /* Called within RCU critical section. */ +@@ -3127,12 +3124,10 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs) + { + FlatView *fv; +- bool result; + + RCU_READ_LOCK_GUARD(); + fv = address_space_to_flatview(as); +- result = flatview_access_valid(fv, addr, len, is_write, attrs); +- return result; ++ return flatview_access_valid(fv, addr, len, is_write, attrs); + } + + static hwaddr +-- +2.27.0 +