diff --git a/CVE-2015-8817-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch b/CVE-2015-8817-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch new file mode 100644 index 0000000..8399338 --- /dev/null +++ b/CVE-2015-8817-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch @@ -0,0 +1,53 @@ +References: bsc#969125 CVE-2015-8817 + +Subject: exec: Respect as_translate_internal length clamp +From: Peter Crosthwaite peter.crosthwaite@xilinx.com Mon Mar 16 22:35:54 2015 -0700 +Date: Mon Apr 27 18:24:19 2015 +0200: +Git: 23820dbfc79d1c9dce090b4c555994f2bb6a69b3 + +address_space_translate_internal will clamp the *plen length argument +based on the size of the memory region being queried. The iommu walker +logic in addresss_space_translate was ignoring this by discarding the +post fn call value of *plen. Fix by just always using *plen as the +length argument throughout the fn, removing the len local variable. + +This fixes a bootloader bug when a single elf section spans multiple +QEMU memory regions. + +Signed-off-by: Peter Crosthwaite +Message-Id: <1426570554-15940-1-git-send-email-peter.crosthwaite@xilinx.com> +Signed-off-by: Paolo Bonzini + +Index: xen-4.6.1-testing/tools/qemu-xen-dir-remote/exec.c +=================================================================== +--- xen-4.6.1-testing.orig/tools/qemu-xen-dir-remote/exec.c ++++ xen-4.6.1-testing/tools/qemu-xen-dir-remote/exec.c +@@ -363,7 +363,6 @@ MemoryRegion *address_space_translate(Ad + IOMMUTLBEntry iotlb; + MemoryRegionSection *section; + MemoryRegion *mr; +- hwaddr len = *plen; + + for (;;) { + section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true); +@@ -376,7 +375,7 @@ MemoryRegion *address_space_translate(Ad + iotlb = mr->iommu_ops->translate(mr, addr, is_write); + addr = ((iotlb.translated_addr & ~iotlb.addr_mask) + | (addr & iotlb.addr_mask)); +- len = MIN(len, (addr | iotlb.addr_mask) - addr + 1); ++ *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1); + if (!(iotlb.perm & (1 << is_write))) { + mr = &io_mem_unassigned; + break; +@@ -387,10 +386,9 @@ MemoryRegion *address_space_translate(Ad + + if (xen_enabled() && memory_access_is_direct(mr, is_write)) { + hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; +- len = MIN(page, len); ++ *plen = MIN(page, *plen); + } + +- *plen = len; + *xlat = addr; + return mr; + } diff --git a/CVE-2015-8818-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch b/CVE-2015-8818-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch new file mode 100644 index 0000000..e746bc9 --- /dev/null +++ b/CVE-2015-8818-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch @@ -0,0 +1,86 @@ +References: bsc#969126 CVE-2015-8818 + +Subject: exec: skip MMIO regions correctly in cpu_physical_memory_write_rom_internal +From: Paolo Bonzini pbonzini@redhat.com Sat Jul 4 00:24:51 2015 +0200 +Date: Mon Jul 6 14:59:11 2015 +0200: +Git: b242e0e0e2969c044a318e56f7988bbd84de1f63 + +Loading the BIOS in the mac99 machine is interesting, because there is a +PROM in the middle of the BIOS region (from 16K to 32K). Before memory +region accesses were clamped, when QEMU was asked to load a BIOS from +0xfff00000 to 0xffffffff it would put even those 16K from the BIOS file +into the region. This is weird because those 16K were not actually +visible between 0xfff04000 and 0xfff07fff. However, it worked. + +After clamping was added, this also worked. In this case, the +cpu_physical_memory_write_rom_internal function split the write in +three parts: the first 16K were copied, the PROM area (second 16K) were +ignored, then the rest was copied. + +Problems then started with commit 965eb2f (exec: do not clamp accesses +to MMIO regions, 2015-06-17). Clamping accesses is not done for MMIO +regions because they can overlap wildly, and MMIO registers can be +expected to perform full-width accesses based only on their address +(with no respect for adjacent registers that could decode to completely +different MemoryRegions). However, this lack of clamping also applied +to the PROM area! cpu_physical_memory_write_rom_internal thus failed +to copy the third range above, i.e. only copied the first 16K of the BIOS. + +In effect, address_space_translate is expecting _something else_ to do +the clamping for MMIO regions if the incoming length is large. This +"something else" is memory_access_size in the case of address_space_rw, +so use the same logic in cpu_physical_memory_write_rom_internal. + +Reported-by: Alexander Graf +Reviewed-by: Laurent Vivier +Tested-by: Laurent Vivier +Fixes: 965eb2f +Signed-off-by: Paolo Bonzini + +Index: xen-4.6.1-testing/tools/qemu-xen-dir-remote/exec.c +=================================================================== +--- xen-4.6.1-testing.orig/tools/qemu-xen-dir-remote/exec.c ++++ xen-4.6.1-testing/tools/qemu-xen-dir-remote/exec.c +@@ -330,6 +330,7 @@ address_space_translate_internal(Address + hwaddr *plen, bool resolve_subpage) + { + MemoryRegionSection *section; ++ MemoryRegion *mr; + Int128 diff; + + section = address_space_lookup_region(d, addr, resolve_subpage); +@@ -339,8 +340,23 @@ address_space_translate_internal(Address + /* Compute offset within MemoryRegion */ + *xlat = addr + section->offset_within_region; + +- diff = int128_sub(section->mr->size, int128_make64(addr)); +- *plen = int128_get64(int128_min(diff, int128_make64(*plen))); ++ mr = section->mr; ++ ++ /* 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. ++ */ ++ if (memory_region_is_ram(mr)) { ++ diff = int128_sub(section->size, int128_make64(addr)); ++ *plen = int128_get64(int128_min(diff, int128_make64(*plen))); ++ } + return section; + } + +@@ -2232,7 +2248,7 @@ static inline void cpu_physical_memory_w + + if (!(memory_region_is_ram(mr) || + memory_region_is_romd(mr))) { +- /* do nothing */ ++ l = memory_access_size(mr, l, addr1); + } else { + addr1 += memory_region_get_ram_addr(mr); + /* ROM/RAM case */ diff --git a/xen.changes b/xen.changes index db8f15f..8d7bee8 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Wed Mar 2 09:47:57 MST 2016 - carnold@suse.com + +- bsc#969125 - VUL-0: CVE-2015-8817: xen: OOB access in + address_space_rw leads to segmentation fault (I) + CVE-2015-8817-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch +- bsc#969126 - VUL-0: CVE-2015-8818: xen: OOB access in + address_space_rw leads to segmentation fault (II) + CVE-2015-8818-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch + ------------------------------------------------------------------- Mon Feb 29 09:40:43 MST 2016 - carnold@suse.com diff --git a/xen.spec b/xen.spec index eeb7990..197eb81 100644 --- a/xen.spec +++ b/xen.spec @@ -15,6 +15,7 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + # needssslcertforbuild Name: xen @@ -264,6 +265,8 @@ Patch295: CVE-2016-2391-qemuu-usb-null-pointer-dereference-in-ohci-module. Patch296: CVE-2016-2391-qemut-usb-null-pointer-dereference-in-ohci-module.patch Patch297: CVE-2016-2538-qemuu-usb-integer-overflow-in-remote-NDIS-message-handling.patch Patch298: CVE-2016-1922-qemuu-i386-null-pointer-dereference-in-vapic_write.patch +Patch299: CVE-2015-8817-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch +Patch300: CVE-2015-8818-qemuu-OOB-access-in-address_space_rw-leads-to-segmentation-fault.patch # Our platform specific patches Patch321: xen-destdir.patch Patch322: vif-bridge-no-iptables.patch @@ -597,6 +600,8 @@ Authors: %patch296 -p1 %patch297 -p1 %patch298 -p1 +%patch299 -p1 +%patch300 -p1 # Our platform specific patches %patch321 -p1 %patch322 -p1