linux/arch/powerpc/platforms
Michael Ellerman 8adddf349f powerpc/mm/radix: Make Radix require HUGETLB_PAGE
Joel reported weird crashes using skiroot_defconfig, in his case we
jumped into an NX page:

  kernel tried to execute exec-protected page (c000000002bff4f0) - exploit attempt? (uid: 0)
  BUG: Unable to handle kernel instruction fetch
  Faulting instruction address: 0xc000000002bff4f0

Looking at the disassembly, we had simply branched to that address:

  c000000000c001bc  49fff335    bl     c000000002bff4f0

But that didn't match the original kernel image:

  c000000000c001bc  4bfff335    bl     c000000000bff4f0 <kobject_get+0x8>

When STRICT_KERNEL_RWX is enabled, and we're using the radix MMU, we
call radix__change_memory_range() late in boot to change page
protections. We do that both to mark rodata read only and also to mark
init text no-execute. That involves walking the kernel page tables,
and clearing _PAGE_WRITE or _PAGE_EXEC respectively.

With radix we may use hugepages for the linear mapping, so the code in
radix__change_memory_range() uses eg. pmd_huge() to test if it has
found a huge mapping, and if so it stops the page table walk and
changes the PMD permissions.

However if the kernel is built without HUGETLBFS support, pmd_huge()
is just a #define that always returns 0. That causes the code in
radix__change_memory_range() to incorrectly interpret the PMD value as
a pointer to a PTE page rather than as a PTE at the PMD level.

We can see this using `dv` in xmon which also uses pmd_huge():

  0:mon> dv c000000000000000
  pgd  @ 0xc000000001740000
  pgdp @ 0xc000000001740000 = 0x80000000ffffb009
  pudp @ 0xc0000000ffffb000 = 0x80000000ffffa009
  pmdp @ 0xc0000000ffffa000 = 0xc00000000000018f   <- this is a PTE
  ptep @ 0xc000000000000100 = 0xa64bb17da64ab07d   <- kernel text

The end result is we treat the value at 0xc000000000000100 as a PTE
and clear _PAGE_WRITE or _PAGE_EXEC, potentially corrupting the code
at that address.

In Joel's specific case we cleared the sign bit in the offset of the
branch, causing a backward branch to turn into a forward branch which
caused us to branch into a non-executable page. However the exact
nature of the crash depends on kernel version, compiler version, and
other factors.

We need to fix radix__change_memory_range() to not use accessors that
depend on HUGETLBFS, but we also have radix memory hotplug code that
uses pmd_huge() etc that will also need fixing. So for now just
disallow the broken combination of Radix with HUGETLBFS disabled.

The only defconfig we have that is affected is skiroot_defconfig, so
turn on HUGETLBFS there so that it still gets Radix.

Fixes: 566ca99af0 ("powerpc/mm/radix: Add dummy radix_enabled()")
Cc: stable@vger.kernel.org # v4.7+
Reported-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2019-04-17 18:50:26 +10:00
..
4xx powerpc/4xx/ocm: Fix fix for phys_addr_t printf warnings 2019-01-11 23:57:20 +11:00
8xx powerpc updates for 4.20 2018-10-26 14:36:21 -07:00
40x PCI: consolidate PCI config entry in drivers/pci 2018-11-23 11:45:34 +09:00
44x powerpc/44x: Force PCI on for CURRITUCK 2019-02-22 00:10:15 +11:00
52xx Kconfig file consolidation for v4.21 2018-12-29 13:40:29 -08:00
82xx powerpc/kconfig: remove CONFIG_6xx 2018-11-26 22:33:37 +11:00
83xx powerpc/83xx: Also save/restore SPRG4-7 during suspend 2019-02-22 00:10:16 +11:00
85xx powerpc/dma: trim the fat from <asm/dma-mapping.h> 2019-02-18 22:41:04 +11:00
86xx powerpc/dma: use the generic direct mapping bypass 2019-02-18 22:41:04 +11:00
512x Kconfig file consolidation for v4.21 2018-12-29 13:40:29 -08:00
amigaone Kconfig file consolidation for v4.21 2018-12-29 13:40:29 -08:00
cell powerpc: remove nargs from __SYSCALL 2019-03-02 14:43:05 +11:00
chrp Merge 5.0-rc4 into char-misc-next 2019-01-28 08:13:52 +01:00
embedded6xx powerpc/wii: remove wii_mmu_mapin_mem2() 2019-02-23 21:04:32 +11:00
maple Kconfig file consolidation for v4.21 2018-12-29 13:40:29 -08:00
pasemi treewide: add checks for the return value of memblock_alloc*() 2019-03-12 10:04:02 -07:00
powermac treewide: add checks for the return value of memblock_alloc*() 2019-03-12 10:04:02 -07:00
powernv powerpc fixes for 5.1 #2 2019-03-16 10:45:17 -07:00
ps3 treewide: add checks for the return value of memblock_alloc*() 2019-03-12 10:04:02 -07:00
pseries powerpc/pseries/mce: Fix misleading print for TLB mutlihit 2019-03-29 16:59:19 +11:00
fsl_uli1575.c of/irq: Refactor interrupt-map parsing 2013-10-24 11:43:04 +01:00
Kconfig Kconfig file consolidation for v4.21 2018-12-29 13:40:29 -08:00
Kconfig.cputype powerpc/mm/radix: Make Radix require HUGETLB_PAGE 2019-04-17 18:50:26 +10:00
Makefile powerpc: Add -Werror at arch/powerpc level 2018-10-19 00:56:17 +11:00