lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 30 Jan 2018 22:22:55 +1100
From:   William Grant <william.grant@...onical.com>
To:     Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>,
        "H. Peter Anvin" <hpa@...or.com>, x86@...nel.org
Cc:     linux-kernel@...r.kernel.org,
        William Grant <william.grant@...onical.com>
Subject: [PATCH] x86: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP

Since commit 92a0f81d8957 ("x86/cpu_entry_area: Move it out of the
fixmap"), i386's CPU_ENTRY_AREA has been mapped to the memory area just
below FIXADDR_START. But already immediately before FIXADDR_START is the
FIX_BTMAP area, which means that early_ioremap can collide with the
entry area.

It's especially bad on PAE where FIX_BTMAP_BEGIN gets aligned to exactly
match CPU_ENTRY_AREA_BASE, so the first early_ioremap slot clobbers the
IDT and causes interrupts during early boot to reset the system.

The overlap wasn't a problem before the CPU entry area was introduced,
as the fixmap has classically been preceded by the pkmap or vmalloc
areas, neither of which is used until early_ioremap is out of the
picture.

Relocate CPU_ENTRY_AREA to below FIX_BTMAP, not just below the permanent
fixmap area.

Signed-off-by: William Grant <william.grant@...onical.com>
---
This fixes a triple fault during early boot of 4.15 with PAE on x86 when
an Intel IOMMU is present. The ACPI table retrieval inside pci_iommu_alloc()
called early_ioremap and unmapped the IDT, and so the exception inside
test_wp_bit triple faulted.

2MiB of i386 kernel address space is wasted in the FIX_BTMAP area that
isn't used after boot, but I couldn't see a better place to put
CPU_ENTRY_AREA. We can't stick it just before the pkmap, since pkmap
doesn't exist when highmem is disabled. We could potentially shift fixmap
down from the top of the address space, but that's already variable due to
reserve_top_address. The only other option would be to shuffle it in
between lowmem and vmalloc, which looks messy due to their variable sizes.

 arch/x86/include/asm/fixmap.h           | 6 ++++--
 arch/x86/include/asm/pgtable_32_types.h | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 64c4a30e0d39..987020a28534 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -137,8 +137,10 @@ enum fixed_addresses {
 
 extern void reserve_top_address(unsigned long reserve);
 
-#define FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+#define FIXADDR_SIZE        (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START       (FIXADDR_TOP - FIXADDR_SIZE)
+#define FIXADDR_ALL_SIZE    (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_ALL_START   (FIXADDR_TOP - FIXADDR_ALL_SIZE)
 
 extern int fixmaps_set;
 
diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h
index ce245b0cdfca..01973e9fd269 100644
--- a/arch/x86/include/asm/pgtable_32_types.h
+++ b/arch/x86/include/asm/pgtable_32_types.h
@@ -44,8 +44,9 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */
  */
 #define CPU_ENTRY_AREA_PAGES	(NR_CPUS * 40)
 
-#define CPU_ENTRY_AREA_BASE				\
-	((FIXADDR_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1)) & PMD_MASK)
+#define CPU_ENTRY_AREA_BASE						\
+	((FIXADDR_ALL_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1))   \
+	 & PMD_MASK)
 
 #define PKMAP_BASE		\
 	((CPU_ENTRY_AREA_BASE - PAGE_SIZE) & PMD_MASK)
-- 
2.15.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ