diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-03-22 20:45:30 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-03-22 20:45:30 +0000 |
commit | b7a3a705b644495b7b578e94e0e9dedf93c4f661 (patch) | |
tree | 2ccf1c628400111f5b0f5069c3452534756e87e8 /softmmu | |
parent | 04ddcda6a2387274b3f31a501be3affd172aea3d (diff) | |
parent | 27801168ecbb34b987d2e92a12369367bf9ac2bf (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.c | 55 |
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 |