All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-arm-kernel@lists.infradead.org,
	Will Deacon <will@kernel.org>,  Marc Zyngier <maz@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	 Ryan Roberts <ryan.roberts@arm.com>,
	Anshuman Khandual <anshuman.khandual@arm.com>,
	 Kees Cook <keescook@chromium.org>,
	Joey Gouly <joey.gouly@arm.com>
Subject: Re: [PATCH v8 42/43] mm: add arch hook to validate mmap() prot flags
Date: Wed, 13 Mar 2024 12:45:22 +0100	[thread overview]
Message-ID: <CAMj1kXFoHRNS+VTOEVna3oMWV9n-2zenDvfURUzRaQ7gvSzFDw@mail.gmail.com> (raw)
In-Reply-To: <ZfGESD3a91lxH367@arm.com>

On Wed, 13 Mar 2024 at 11:47, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Wed, Mar 13, 2024 at 12:23:24AM +0100, Ard Biesheuvel wrote:
> > On Tue, 12 Mar 2024 at 20:53, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > > On Wed, Feb 14, 2024 at 01:29:28PM +0100, Ard Biesheuvel wrote:
> > > > diff --git a/mm/mmap.c b/mm/mmap.c
> > > > index d89770eaab6b..977a8c3fd9f5 100644
> > > > --- a/mm/mmap.c
> > > > +++ b/mm/mmap.c
> > > > @@ -1229,6 +1229,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
> > > >               if (!(file && path_noexec(&file->f_path)))
> > > >                       prot |= PROT_EXEC;
> > > >
> > > > +     if (!arch_validate_mmap_prot(prot, addr))
> > > > +             return -EACCES;
> > > > +
> > > >       /* force arch specific MAP_FIXED handling in get_unmapped_area */
> > > >       if (flags & MAP_FIXED_NOREPLACE)
> > > >               flags |= MAP_FIXED;
> > >
> > > While writing the pull request for Linus (and looking to justify this
> > > change), I realised that we already have arch_validate_flags() that can
> > > do a similar check but on VM_* flags instead of PROT_* (we use it for
> > > VM_MTE checks). What was the reason for adding a new hook?
> [...]
> > > The only
> > > difference is that here it returns -EACCESS while on
> > > arch_validate_flags() failure it would return -EINVAL. It probably makes
> > > more to return -EACCESS as it matches map_deny_write_exec() but with
> > > your patches we are inconsistent between mmap() and mprotect() errors
> > > (the latter is still -EINVAL).
> >
> > Yes. Looking at it now, it would be better to add a single arch hook
> > to map_deny_write_exec(), and use that instead.
>
> This would work and matches the API better. Another way to look at the
> arm64 WXN feature is to avoid bothering with with the checks knowing
> that the hardware enforces XN when a permission is W. So it can be seen
> as a choice irrespective of the user PROT_EXEC|PROT_WRITE permission.
> But it's still an ABI change, so I guess better to be upfront with the
> user and reject such mmap()/mprotect() permission combinations.
>

Yes, that was the idea in the original patch.

> However, I've been looking through specs and realised that SCTLR_ELx.WXN
> is RES0 when the permission indirection is enabled (FEAT_PIE from the
> 2022 specs, hopefully you have access to it).

The latest public version of the ARM ARM does not cover FEAT_PIE at all.

> And while apparently WXN
> gets better as it allows separate EL0/EL1 controls, it seems to only
> apply when the base permission is RWX and the XN is toggled based on the
> overlay permission (pkeys which Joey is working on). So it looks like
> what the architects had in mind is optimising RW/RX switching via
> overlays (no syscalls) but keeping the base permission RWX. The
> traditional WXN hardening via SCTLR_EL1 disappeared.
>
> (adding Joey to the thread, he contributed the PIE support)
>

PIE sounds useful to implement things like JITs in user space, where
you want a certain mapping to transition to RW while all other CPUs
retain RX access concurrently.

WXN is intended to be static, where a single bit sets the system-wide
policy for all kernel and user space code.

It's rather unfortunate that FEAT_PIE relies on RWX mappings and
therefore needs to deprecate WXN entirely. It would have been nice to
have something like this for the kernel, which never has a need for
RWX mappings or transitioning mappings between RX and RW like that,
and so overlays don't seem to be a great fit.

> > > It also got me thinking on whether we could use this as a hardened
> > > version of the MDWE feature instead a CPU feature (though we'd end up
> > > context-switching this SCTLR_EL1 bit). I think your patches have been
> > > around before the MDWE feature was added to the kernel.
> >
> > Indeed.
> >
> > MDWE looks like a good match in principle, but combining the two seems tricky:
> > - EL1 is going to flip between WXN protection on and off depending on
> > which setting it is using for EL0;
> > - context switching SCTLR_EL1.WXN may become costly in terms of TLB
> > maintenance, unless we cheat and ignore the kernel mappings (which
> > should work as expected regardless of the value of SCTLR_EL1.WXN);
> >
> > If we can find a reasonable strategy to manage the TLB maintenance
> > that does not leave EL1 behind, I'm happy to explore this further. But
> > perhaps WXN should simply be treated as MDWE always-on for all
> > processes.
>
> Ah, I did not realise this bit can be cached in the TLB. So this doesn't
> really work (and the Arm ARM is also vague about whether it's cached per
> ASID or not).
>
> > > Sorry for not catching this early.
> >
> > No worries - it's more likely to be useful if we get this right.
>
> Given that with PIE this feature no longer works, I'll revert these two
> patches for now. We should revisit it in combination with PIE and POE
> (overlays) but it does look like the semantics are slightly different
> (unless I misread the specs). If we want a global MDWE=on on the command
> line, this can be generic.
>

I looked into this a bit more, and MDWE is a bit stricter than WXN,
and therefore less suitable for enabling system-wide. It disallows
adding executable permissions entirely, as well as adding write
permissions to a mapping that is already executable. WXN just
disallows setting both at the same time.

So using the same hook makes sense, but combining the logic beyond
that seems problematic too.

I'll code it up in any case to see what it looks like.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2024-03-13 11:45 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-14 12:28 [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1 Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 01/43] arm64: kernel: Manage absolute relocations in code built under pi/ Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 02/43] arm64: kernel: Don't rely on objcopy to make code under pi/ __init Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 03/43] arm64: head: move relocation handling to C code Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 04/43] arm64: idreg-override: Move to early mini C runtime Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 05/43] arm64: kernel: Remove early fdt remap code Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 06/43] arm64: head: Clear BSS and the kernel page tables in one go Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 07/43] arm64: Move feature overrides into the BSS section Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 08/43] arm64: head: Run feature override detection before mapping the kernel Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 09/43] arm64: head: move dynamic shadow call stack patching into early C runtime Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 10/43] arm64: cpufeature: Add helper to test for CPU feature overrides Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 11/43] arm64: kaslr: Use feature override instead of parsing the cmdline again Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 12/43] arm64: idreg-override: Create a pseudo feature for rodata=off Ard Biesheuvel
2024-02-14 12:28 ` [PATCH v8 13/43] arm64: Add helpers to probe local CPU for PAC and BTI support Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 14/43] arm64: head: allocate more pages for the kernel mapping Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 15/43] arm64: head: move memstart_offset_seed handling to C code Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 16/43] arm64: mm: Make kaslr_requires_kpti() a static inline Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 17/43] arm64: mmu: Make __cpu_replace_ttbr1() out of line Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 18/43] arm64: head: Move early kernel mapping routines into C code Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 19/43] arm64: mm: Use 48-bit virtual addressing for the permanent ID map Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 20/43] arm64: pgtable: Decouple PGDIR size macros from PGD/PUD/PMD levels Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 21/43] arm64: kernel: Create initial ID map from C code Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 22/43] arm64: mm: avoid fixmap for early swapper_pg_dir updates Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 23/43] arm64: mm: omit redundant remap of kernel image Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 24/43] arm64: Revert "mm: provide idmap pointer to cpu_replace_ttbr1()" Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 25/43] arm64: mm: Handle LVA support as a CPU feature Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 26/43] arm64: mm: Add feature override support for LVA Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 27/43] arm64: Avoid #define'ing PTE_MAYBE_NG to 0x0 for asm use Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 28/43] arm64: Add ESR decoding for exceptions involving translation level -1 Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 29/43] arm64: mm: Wire up TCR.DS bit to PTE shareability fields Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 30/43] arm64: mm: Add LPA2 support to phys<->pte conversion routines Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 31/43] arm64: mm: Add definitions to support 5 levels of paging Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 32/43] arm64: mm: add LPA2 and 5 level paging support to G-to-nG conversion Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 33/43] arm64: Enable LPA2 at boot if supported by the system Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 34/43] arm64: mm: Add 5 level paging support to fixmap and swapper handling Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 35/43] arm64: kasan: Reduce minimum shadow alignment and enable 5 level paging Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 36/43] arm64: mm: Add support for folding PUDs at runtime Ard Biesheuvel
2024-02-29 14:17   ` Ryan Roberts
2024-02-29 23:01     ` Nathan Chancellor
2024-03-01  8:54       ` Ryan Roberts
2024-03-01  9:10         ` Ard Biesheuvel
2024-03-01  9:37           ` Ard Biesheuvel
2024-03-01  9:47             ` Ryan Roberts
2024-03-01 10:22               ` Ryan Roberts
2024-02-14 12:29 ` [PATCH v8 37/43] arm64: ptdump: Disregard unaddressable VA space Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 38/43] arm64: ptdump: Deal with translation levels folded at runtime Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 39/43] arm64: kvm: avoid CONFIG_PGTABLE_LEVELS for runtime levels Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 40/43] arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 41/43] arm64: defconfig: Enable LPA2 support Ard Biesheuvel
2024-02-14 12:29 ` [PATCH v8 42/43] mm: add arch hook to validate mmap() prot flags Ard Biesheuvel
2024-03-12 19:53   ` Catalin Marinas
2024-03-12 23:23     ` Ard Biesheuvel
2024-03-13 10:47       ` Catalin Marinas
2024-03-13 11:45         ` Ard Biesheuvel [this message]
2024-03-13 15:31           ` Catalin Marinas
2024-02-14 12:29 ` [PATCH v8 43/43] arm64: mm: add support for WXN memory translation attribute Ard Biesheuvel
2024-02-16 17:35 ` [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1 Catalin Marinas
2024-02-16 18:23   ` Ard Biesheuvel
2024-02-16 22:34     ` Ard Biesheuvel

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=CAMj1kXFoHRNS+VTOEVna3oMWV9n-2zenDvfURUzRaQ7gvSzFDw@mail.gmail.com \
    --to=ardb@kernel.org \
    --cc=anshuman.khandual@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=joey.gouly@arm.com \
    --cc=keescook@chromium.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=will@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.