From: Michael Ellerman <patch-notifications@ellerman.id.au>
To: Michael Ellerman <mpe@ellerman.id.au>, linuxppc-dev@ozlabs.org
Cc: stewart@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com,
joel@jms.id.au
Subject: Re: powerpc/mm/radix: Make Radix require HUGETLB_PAGE
Date: Mon, 22 Apr 2019 00:07:21 +1000 (AEST) [thread overview]
Message-ID: <44nBNn6lVxz9sB3@ozlabs.org> (raw)
In-Reply-To: <20190417074140.25130-1-mpe@ellerman.id.au>
On Wed, 2019-04-17 at 07:41:40 UTC, Michael Ellerman wrote:
> 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.
>
> Unfortunately the combination of _PAGE_PTE and _PAGE_PRESENT in the
> high bits of the PMD entry give us 0xc in the top nibble which means
> the PMD entry happens to look like a valid pointer into the linear
> mapping.
>
> We can see this using `dv` in xmon:
>
> 0:mon> dv c000000000000000
> pgd @ 0xc000000001740000
> pgdp @ 0xc000000001740000 = 0x80000000ffffb009
> pudp @ 0xc0000000ffffb000 = 0x80000000ffffa009
> pmdp @ 0xc0000000ffffa000 = 0xc00000000000018f <- not a pointer
> 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: 566ca99af026 ("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>
Applied to powerpc fixes.
https://git.kernel.org/powerpc/c/8adddf349fda0d3de2f6bb41ddf838cb
cheers
prev parent reply other threads:[~2019-04-21 14:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-17 7:41 [PATCH] powerpc/mm/radix: Make Radix require HUGETLB_PAGE Michael Ellerman
2019-04-17 8:51 ` Michael Ellerman
2019-04-21 14:07 ` Michael Ellerman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44nBNn6lVxz9sB3@ozlabs.org \
--to=patch-notifications@ellerman.id.au \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=joel@jms.id.au \
--cc=linuxppc-dev@ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=stewart@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).