|
| 1 | +From 418ade7849ce7641c0f7333718caf5091a02fd4c Mon Sep 17 00:00:00 2001 |
| 2 | +From: Richard Henderson < [email protected]> |
| 3 | +Date: Tue, 21 Jun 2022 08:38:29 -0700 |
| 4 | +Subject: [PATCH] softmmu: Always initialize xlat in |
| 5 | + address_space_translate_for_iotlb |
| 6 | + |
| 7 | +The bug is an uninitialized memory read, along the translate_fail |
| 8 | +path, which results in garbage being read from iotlb_to_section, |
| 9 | +which can lead to a crash in io_readx/io_writex. |
| 10 | + |
| 11 | +The bug may be fixed by writing any value with zero |
| 12 | +in ~TARGET_PAGE_MASK, so that the call to iotlb_to_section using |
| 13 | +the xlat'ed address returns io_mem_unassigned, as desired by the |
| 14 | +translate_fail path. |
| 15 | + |
| 16 | +It is most useful to record the original physical page address, |
| 17 | +which will eventually be logged by memory_region_access_valid |
| 18 | +when the access is rejected by unassigned_mem_accepts. |
| 19 | + |
| 20 | +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1065 |
| 21 | +Signed-off-by: Richard Henderson < [email protected]> |
| 22 | +Reviewed-by: Peter Maydell < [email protected]> |
| 23 | + |
| 24 | +--- |
| 25 | + softmmu/physmem.c | 13 ++++++++++++- |
| 26 | + 1 file changed, 12 insertions(+), 1 deletion(-) |
| 27 | + |
| 28 | +diff --git a/softmmu/physmem.c b/softmmu/physmem.c |
| 29 | +index fb16be57a6c6..dc3c3e5f2e70 100644 |
| 30 | +--- a/softmmu/physmem.c |
| 31 | ++++ b/softmmu/physmem.c |
| 32 | +@@ -669,7 +669,7 @@ void tcg_iommu_init_notifier_list(CPUState *cpu) |
| 33 | + |
| 34 | + /* Called from RCU critical section */ |
| 35 | + MemoryRegionSection * |
| 36 | +-address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, |
| 37 | ++address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, |
| 38 | + hwaddr *xlat, hwaddr *plen, |
| 39 | + MemTxAttrs attrs, int *prot) |
| 40 | + { |
| 41 | +@@ -678,6 +678,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, |
| 42 | + IOMMUMemoryRegionClass *imrc; |
| 43 | + IOMMUTLBEntry iotlb; |
| 44 | + int iommu_idx; |
| 45 | ++ hwaddr addr = orig_addr; |
| 46 | + AddressSpaceDispatch *d = |
| 47 | + qatomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch); |
| 48 | + |
| 49 | +@@ -722,6 +723,16 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, |
| 50 | + return section; |
| 51 | + |
| 52 | + translate_fail: |
| 53 | ++ /* |
| 54 | ++ * We should be given a page-aligned address -- certainly |
| 55 | ++ * tlb_set_page_with_attrs() does so. The page offset of xlat |
| 56 | ++ * is used to index sections[], and PHYS_SECTION_UNASSIGNED = 0. |
| 57 | ++ * The page portion of xlat will be logged by memory_region_access_valid() |
| 58 | ++ * when this memory access is rejected, so use the original untranslated |
| 59 | ++ * physical address. |
| 60 | ++ */ |
| 61 | ++ assert((orig_addr & ~TARGET_PAGE_MASK) == 0); |
| 62 | ++ *xlat = orig_addr; |
| 63 | + return &d->map.sections[PHYS_SECTION_UNASSIGNED]; |
| 64 | + } |
0 commit comments