69 lines
2.6 KiB
Diff
69 lines
2.6 KiB
Diff
From f9b1194f6cf3c0b916e01cc6e76f2e6226cf11c5 Mon Sep 17 00:00:00 2001
|
|
From: yinyongkang <yinyongkang@kylinos.cn>
|
|
Date: Fri, 15 Jul 2022 10:49:38 +0800
|
|
Subject: [PATCH] softmmu: Always initialize xlat in
|
|
address_space_translate_for_iotlb
|
|
|
|
The bug is an uninitialized memory read, along the translate_fail
|
|
path, which results in garbage being read from iotlb_to_section,
|
|
which can lead to a crash in io_readx/io_writex.
|
|
|
|
The bug may be fixed by writing any value with zero
|
|
in ~TARGET_PAGE_MASK, so that the call to iotlb_to_section using
|
|
the xlat'ed address returns io_mem_unassigned, as desired by the
|
|
translate_fail path.
|
|
|
|
It is most useful to record the original physical page address,
|
|
which will eventually be logged by memory_region_access_valid
|
|
when the access is rejected by unassigned_mem_accepts.
|
|
|
|
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1065
|
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
|
Message-Id: <20220621153829.366423-1-richard.henderson@linaro.org>
|
|
---
|
|
exec.c | 13 ++++++++++++-
|
|
1 file changed, 12 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/exec.c b/exec.c
|
|
index 8822c241d8..e785178d73 100644
|
|
--- a/exec.c
|
|
+++ b/exec.c
|
|
@@ -719,7 +719,7 @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
|
|
|
|
/* Called from RCU critical section */
|
|
MemoryRegionSection *
|
|
-address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
|
|
+address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr,
|
|
hwaddr *xlat, hwaddr *plen,
|
|
MemTxAttrs attrs, int *prot)
|
|
{
|
|
@@ -728,6 +728,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
|
|
IOMMUMemoryRegionClass *imrc;
|
|
IOMMUTLBEntry iotlb;
|
|
int iommu_idx;
|
|
+ hwaddr addr = orig_addr;
|
|
AddressSpaceDispatch *d = atomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch);
|
|
|
|
for (;;) {
|
|
@@ -771,6 +772,16 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
|
|
return section;
|
|
|
|
translate_fail:
|
|
+ /*
|
|
+ * We should be given a page-aligned address -- certainly
|
|
+ * tlb_set_page_with_attrs() does so. The page offset of xlat
|
|
+ * is used to index sections[], and PHYS_SECTION_UNASSIGNED = 0.
|
|
+ * The page portion of xlat will be logged by memory_region_access_valid()
|
|
+ * when this memory access is rejected, so use the original untranslated
|
|
+ * physical address.
|
|
+ */
|
|
+ assert((orig_addr & ~TARGET_PAGE_MASK) == 0);
|
|
+ *xlat = orig_addr;
|
|
return &d->map.sections[PHYS_SECTION_UNASSIGNED];
|
|
}
|
|
#endif
|
|
--
|
|
2.27.0
|
|
|