linux-uconsole/arch/powerpc/platforms
Michael Ellerman 087341c0f4 powerpc/mm/radix: Make Radix require HUGETLB_PAGE
commit 8adddf349f upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-02 09:58:55 +02:00
..
4xx powerpc/4xx: Fix error return path in ppc4xx_msi_probe() 2018-08-03 20:08:20 +10:00
8xx powerpc/8xx: Remove RTC clock on 88x 2018-06-04 00:39:18 +10:00
40x License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
44x powerpc/44x/fsp2: Add irq error handlers 2017-12-11 13:03:34 +11:00
52xx powerpc/Makefiles: Convert ifeq to ifdef where possible 2018-08-08 00:32:36 +10:00
82xx License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
83xx powerpc/83xx: Also save/restore SPRG4-7 during suspend 2019-03-23 20:10:07 +01:00
85xx powerpc/platforms/85xx: fix t1042rdb_diu.c build errors & warning 2018-08-08 00:32:33 +10:00
86xx powerpc: Use pr_warn instead of pr_warning 2017-12-04 11:54:34 +11:00
512x powerpc: Use pr_warn instead of pr_warning 2017-12-04 11:54:34 +11:00
amigaone License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cell Merge branch 'akpm' (patches from Andrew) 2018-08-17 16:49:31 -07:00
chrp chrp/nvram.c: add MODULE_LICENSE() 2018-07-19 14:38:46 +10:00
embedded6xx powerpc/wii: properly disable use of BATs when requested. 2019-03-23 20:10:07 +01:00
maple powerpc: use time64_t in read_persistent_clock 2018-06-03 20:43:33 +10:00
pasemi powerpc/pasemi: Use pr_err/pr_warn... for kernel messages 2018-08-08 00:32:31 +10:00
powermac powerpc: consolidate -mno-sched-epilog into FTRACE flags 2019-01-13 09:51:05 +01:00
powernv powerpc/powernv/ioda: Fix locked_vm counting for memory used by IOMMU tables 2019-04-05 22:33:01 +02:00
ps3 powerpc: remove unused to_tm() helper 2018-06-03 20:43:34 +10:00
pseries powerpc/pseries: Perform full re-add of CPU for topology update post-migration 2019-04-05 22:33:13 +02:00
fsl_uli1575.c
Kconfig powerpc/cell: Remove axonram driver 2018-01-28 17:00:36 +11:00
Kconfig.cputype powerpc/mm/radix: Make Radix require HUGETLB_PAGE 2019-05-02 09:58:55 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00