diff --git a/memory-clamp-cached-translation-in-case-it-points-to.patch b/memory-clamp-cached-translation-in-case-it-points-to.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb11fcdde8e65cfa5e8d92d78156b6b244800995 --- /dev/null +++ b/memory-clamp-cached-translation-in-case-it-points-to.patch @@ -0,0 +1,72 @@ +From fdcfc9cf131b905ef7ad851a132bc6d0097e4250 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 13 Jan 2021 14:50:59 +0800 +Subject: [PATCH] memory: clamp cached translation in case it points to an MMIO + region + +In using the address_space_translate_internal API, address_space_cache_init +forgot one piece of advice that can be found in the code for +address_space_translate_internal: + + /* MMIO registers can be expected to perform full-width accesses based only + * on their address, without considering adjacent registers that could + * decode to completely different MemoryRegions. When such registers + * exist (e.g. I/O ports 0xcf8 and 0xcf9 on most PC chipsets), MMIO + * regions overlap wildly. For this reason we cannot clamp the accesses + * here. + * + * If the length is small (as is the case for address_space_ldl/stl), + * everything works fine. If the incoming length is large, however, + * the caller really has to do the clamping through memory_access_size. + */ + +address_space_cache_init is exactly one such case where "the incoming length +is large", therefore we need to clamp the resulting length---not to +memory_access_size though, since we are not doing an access yet, but to +the size of the resulting section. This ensures that subsequent accesses +to the cached MemoryRegionSection will be in range. + +With this patch, the enclosed testcase notices that the used ring does +not fit into the MSI-X table and prints a "qemu-system-x86_64: Cannot map used" +error. + +Signed-off-by: Paolo Bonzini +(cherry-picked from 4bfb024b) +Fix CVE-2020-27821 +Signed-off-by: Alex Chen +--- + exec.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/exec.c b/exec.c +index 85c6d80353..8822c241d8 100644 +--- a/exec.c ++++ b/exec.c +@@ -3834,6 +3834,7 @@ int64_t address_space_cache_init(MemoryRegionCache *cache, + AddressSpaceDispatch *d; + hwaddr l; + MemoryRegion *mr; ++ Int128 diff; + + assert(len > 0); + +@@ -3842,6 +3843,16 @@ int64_t address_space_cache_init(MemoryRegionCache *cache, + d = flatview_to_dispatch(cache->fv); + cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true); + ++ /* ++ * cache->xlat is now relative to cache->mrs.mr, not to the section itself. ++ * Take that into account to compute how many bytes are there between ++ * cache->xlat and the end of the section. ++ */ ++ ++ diff = int128_sub(cache->mrs.size, ++ int128_make64(cache->xlat - cache->mrs.offset_within_region)); ++ l = int128_get64(int128_min(diff, int128_make64(l))); ++ + mr = cache->mrs.mr; + memory_region_ref(mr); + if (memory_access_is_direct(mr, is_write)) { +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 820c815616aa4414f1b46580672911a9ab30951c..67fddad5698dda2017619ff9f16a6bb85a752283 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 32 +Release: 33 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 @@ -233,6 +233,7 @@ Patch0220: hw-ehci-check-return-value-of-usb_packet_map.patch Patch0221: hw-usb-hcd-ohci-check-len-and-frame_number-variables.patch Patch0222: hw-net-e1000e-advance-desc_offset-in-case-of-null-de.patch Patch0223: target-arm-Fix-write-redundant-values-to-kvm.patch +Patch0224: memory-clamp-cached-translation-in-case-it-points-to.patch BuildRequires: flex BuildRequires: bison @@ -578,6 +579,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Jan 15 2021 Huawei Technologies Co., Ltd +- memory: clamp cached translation in case it points to an MMIO region + * Wed Dec 9 2020 Huawei Technologies Co., Ltd - target/arm: Fix write redundant values to kvm