[PATCH v4 0/7] ARM: add vmap'ed stack support

Ard Biesheuvel ardb at kernel.org
Mon Nov 22 01:28:09 PST 2021


This series enables support on ARM for vmap'ed task and IRQ stacks in
the kernel. This is an important hardening feature that terminates tasks
on inadvertent or deliberate accesses past the stack pointer, which
might otherwise go completely unnoticed.

Since having an accurate backtrace is especially important in such
cases, this series includes some enhancements to the unwinder and to
some hand rolled unwind info to increase the likelihood that a backtrace
can be generated when relying on the ARM unwinder. The frame pointer
unwinder turns out to be rather bullet proof in this context, and does
not need any such enhancements.

According to a quick survey I did, compiler generated code puts a single
stack push as the first instruction in about 2/3 of the cases, which the
unwinder can deal with after applying patch #4, even if this push
faulted because of a stack overflow. In the remaining cases, the
compiler tends to fall back to R11 or R7 as the frame pointer (on ARM
or Thumb-2, respectively), or emit partial unwind frames for the part of
the function that runs before the stack frame is set up, and the part
that runs inside the stack frame. In either case, the unwinder can deal
with such occurrences as they don't rely on the stack pointer directly.

Changes since v3:
- avoid using the wrong virtual to physical translation on the stack
  pointer in the suspend/cpuidle code path, 
- check whether SP points into the linear map rather than whether it
  points into the overflow stack specifically, so that other stacks
  are disregarded as well,
- use a per-CPU pointer rather than a per-CPU allocation for the
  overflow stack, so the stack itself can be allocated via the page
  allocator,
- avoid deliberately corrupting any task userland state, by repurposing
  the padding in the per-mode stacks as scratch space to hold a single
  GPR value, and rejigging the __bad_stack handler to only require a
  single GPR to load the overflow stack address into SP.

Changes since v2:
- rebase onto v5.16-rc1
- incorporate Nico's review feedback

Changes since v1:
- handle a missed corner case in svc_entry code, and while at it,
  streamline it a bit, especially for Thumb-2, which no longer
  needs to move SP into R0 twice to do the overflow check and the
  alignment check,
- improve the memcpy patch so that we no longer need to push the frame
  pointer separately,
- add Keith's tested-by

Patches #1, #2 and #3 update the ARM asm string routines to align more
closely with the compiler's approach in terms of unwind tables,
increasing the likelihood that we can unwind them in case of a stack
overflow.

Patches #5 and #6 do some preparatory refactoring for the entry and
switch_to code, to reduce clutter in patch #7.

Patch #7 wires up the generic support, and adds the entry code to detect
and deal with stack overflows.

This series applies onto my IRQ stacks series sent out earlier:
https://lore.kernel.org/linux-arm-kernel/20211115084732.3704393-1-ardb@kernel.org/

Cc: Russell King <linux at armlinux.org.uk>
Cc: Nicolas Pitre <nico at fluxnic.net>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Kees Cook <keescook at chromium.org>
Cc: Keith Packard <keithpac at amazon.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Tony Lindgren <tony at atomide.com>

Ard Biesheuvel (7):
  ARM: memcpy: use frame pointer as unwind anchor
  ARM: memmove: use frame pointer as unwind anchor
  ARM: memset: clean up unwind annotations
  ARM: unwind: disregard unwind info before stack frame is set up
  ARM: switch_to: clean up Thumb2 code path
  ARM: entry: rework stack realignment code in svc_entry
  ARM: implement support for vmap'ed stacks

 arch/arm/Kconfig                   |   1 +
 arch/arm/include/asm/page.h        |   4 +
 arch/arm/include/asm/thread_info.h |   8 ++
 arch/arm/kernel/entry-armv.S       | 139 +++++++++++++++++---
 arch/arm/kernel/entry-header.S     |  37 ++++++
 arch/arm/kernel/irq.c              |   9 +-
 arch/arm/kernel/setup.c            |   8 +-
 arch/arm/kernel/sleep.S            |   8 ++
 arch/arm/kernel/traps.c            |  80 ++++++++++-
 arch/arm/kernel/unwind.c           |  19 ++-
 arch/arm/kernel/vmlinux.lds.S      |   4 +-
 arch/arm/lib/copy_from_user.S      |  13 +-
 arch/arm/lib/copy_template.S       |  67 ++++------
 arch/arm/lib/copy_to_user.S        |  13 +-
 arch/arm/lib/memcpy.S              |  13 +-
 arch/arm/lib/memmove.S             |  60 +++------
 arch/arm/lib/memset.S              |   7 +-
 17 files changed, 349 insertions(+), 141 deletions(-)

-- 
2.30.2



More information about the linux-arm-kernel mailing list