aboutsummaryrefslogtreecommitdiff
path: root/softmmu
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-03-22 20:45:30 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-03-22 20:45:30 +0000
commitb7a3a705b644495b7b578e94e0e9dedf93c4f661 (patch)
tree2ccf1c628400111f5b0f5069c3452534756e87e8 /softmmu
parent04ddcda6a2387274b3f31a501be3affd172aea3d (diff)
parent27801168ecbb34b987d2e92a12369367bf9ac2bf (diff)
Merge tag 'pull-request-2022-03-21' of https://gitlab.com/thuth/qemu into staging
* Fix stack-overflow due to recursive DMA in intel-hda (CVE-2021-3611) * Fix heap overflow due to recursive DMA in sdhci code # gpg: Signature made Mon 21 Mar 2022 16:14:36 GMT # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2022-03-21' of https://gitlab.com/thuth/qemu: tests/qtest/fuzz-sdcard-test: Add reproducer for OSS-Fuzz (Issue 29225) hw/sd/sdhci: Prohibit DMA accesses to devices hw/sd/sdhci: Honor failed DMA transactions tests/qtest/intel-hda-test: Add reproducer for issue #542 hw/audio/intel-hda: Restrict DMA engine to memories (not MMIO devices) hw/audio/intel-hda: Do not ignore DMA overrun errors softmmu/physmem: Introduce MemTxAttrs::memory field and MEMTX_ACCESS_ERROR softmmu/physmem: Simplify flatview_write and address_space_access_valid Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'softmmu')
-rw-r--r--softmmu/physmem.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 43ae70fbe2..4e1b27a20e 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -42,6 +42,7 @@
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/qemu-print.h"
+#include "qemu/log.h"
#include "qemu/memalign.h"
#include "exec/memory.h"
#include "exec/ioport.h"
@@ -2760,6 +2761,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,
@@ -2774,7 +2802,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
@@ -2816,14 +2847,14 @@ 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;
+ if (!flatview_access_allowed(mr, attrs, addr, len)) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ return flatview_write_continue(fv, addr, attrs, buf, len,
+ addr1, l, mr);
}
/* Called within RCU critical section. */
@@ -2840,7 +2871,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);
@@ -2883,6 +2917,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);
}
@@ -3139,12 +3176,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