mbox series

[v6,0/9] arm64: add support for WXN

Message ID 20220701130444.2945106-1-ardb@kernel.org (mailing list archive)
Headers show
Series arm64: add support for WXN | expand

Message

Ard Biesheuvel July 1, 2022, 1:04 p.m. UTC
This series covers the remaining changes that are needed to enable WXN
support on arm64 now that a lot of the prerequisite work has been queued
up. WXN support is desirable for robustness, given that writable,
executable mappings of memory are too easy to subvert, and in the
kernel, we never rely on such mappings anyway.

Setting SCTLR_ELx.WXN makes all writable mappings implicitly
non-executable, and when set at EL1, it affects EL0 as well as EL1. This
means we need some diligence on the part of user space, but fortunately,
most JITs and other user space components that actually need to
manipulate the contents of their own executable code use split views on
the same memory, or switch between RW- and R-X and back. (One notable
exception is V8, which recently switched back to a full RWX mappings
based JIT)

So on the user space side, we need a couple of minor tweaks to validate
the mmap()/mprotect() arguments when WXN is in effect, and to handle any
faults that might occur on such mappings.

On the kernel side, it is mostly about ensuring that we don't rely on
writable, executable mappings, even during early boot. So for this
reason, the two remaining sequences that create the kernel mapping are
merged, moving the more elaborate logic to set the right attributes into
a C implementation that executes from the ID map. This also allows us to
move the relocation code into C as well, which only lived in asm because
it runs before we have a stack.

Finally, some cleanups are provided for the KASLR code, mainly to ensure
that the early code's decision to use nG mappings or not is based on the
exact same criteria.

(v5 was a subset of v4 without the WXN specific pieces)

Changes since v4: [0]
- don't move __ro_after_init section now that we no longer need to,
- don't complicate the asm kernel mapping routines further, but instead,
  merge the two existing passes into one implemented in C,
- deal with rodata=off on WXN enabled builds (i.e., turn off WXN as
  well),
- add some acks from Kees

[0] https://lore.kernel.org/linux-arm-kernel/20220613144550.3760857-1-ardb@kernel.org/

Cc: Marc Zyngier <maz@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>

Ard Biesheuvel (9):
  arm64: kaslr: use an ordinary command line param for nokaslr
  arm64: kaslr: don't pretend KASLR is enabled if offset <
    MIN_KIMG_ALIGN
  arm64: kaslr: drop special case for ThunderX in kaslr_requires_kpti()
  arm64: head: allocate more pages for the kernel mapping
  arm64: head: move early kernel mapping and relocation code to C code
  arm64: mm: avoid fixmap for early swapper_pg_dir updates
  arm64: mm: omit redundant remap of kernel image
  mm: add arch hook to validate mmap() prot flags
  arm64: mm: add support for WXN memory translation attribute

 arch/arm64/Kconfig                      |  11 +
 arch/arm64/include/asm/cpufeature.h     |   9 +
 arch/arm64/include/asm/kasan.h          |   2 -
 arch/arm64/include/asm/kernel-pgtable.h |  11 +-
 arch/arm64/include/asm/memory.h         |  11 +
 arch/arm64/include/asm/mman.h           |  36 ++
 arch/arm64/include/asm/mmu.h            |   2 +-
 arch/arm64/include/asm/mmu_context.h    |  30 +-
 arch/arm64/include/asm/pgtable-prot.h   |   2 +
 arch/arm64/kernel/Makefile              |   4 +-
 arch/arm64/kernel/cpufeature.c          |  14 +-
 arch/arm64/kernel/head.S                | 157 +-------
 arch/arm64/kernel/idreg-override.c      |  15 -
 arch/arm64/kernel/image-vars.h          |  17 +
 arch/arm64/kernel/kaslr.c               |   8 +-
 arch/arm64/kernel/pi/Makefile           |   2 +-
 arch/arm64/kernel/pi/early_map_kernel.c | 381 ++++++++++++++++++++
 arch/arm64/kernel/pi/kaslr_early.c      | 112 ------
 arch/arm64/kernel/vmlinux.lds.S         |  13 +-
 arch/arm64/mm/kasan_init.c              |  15 -
 arch/arm64/mm/mmu.c                     | 150 +++-----
 arch/arm64/mm/proc.S                    |  24 ++
 include/linux/mman.h                    |  15 +
 mm/mmap.c                               |   3 +
 24 files changed, 630 insertions(+), 414 deletions(-)
 create mode 100644 arch/arm64/kernel/pi/early_map_kernel.c
 delete mode 100644 arch/arm64/kernel/pi/kaslr_early.c