Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARMv8-M: Implement stack limit checking for Secure/Non-secure stack pointers #6373

Closed
ioannisg opened this issue Feb 26, 2018 · 1 comment

Comments

@ioannisg
Copy link
Member

commented Feb 26, 2018

ARMv8-M implementations may have stack limit registers to allow stack protection, which is valuable, particularly, when the processor implementation includes the optional ARM Security Extension.

Stack limit checking is enforced during the creation of a stack frame. It prevents stack pointer to decent below values that, possibly, cross security boundaries (i.e. secure and non-secure memory regions).

This task concerns the integration of ARM stack limit checking in the ARM core.

  • Integrate Interrupt Stack limit checking in the ARM core

  • Integrate Main Thread stack limit checking in the ARM core

  • Thread stack protection with stack-pointer-based limit checking

  • Protection for Secure images

@ioannisg ioannisg added this to In progress in Trusted Execution Feb 26, 2018

@ioannisg ioannisg moved this from In progress to To do in Trusted Execution Feb 26, 2018

@ioannisg ioannisg self-assigned this Mar 5, 2018

@ioannisg ioannisg moved this from To do to In progress in Trusted Execution Mar 5, 2018

@ioannisg

This comment has been minimized.

Copy link
Member Author

commented Mar 5, 2018

Prerequisites:

  • ARMv8-M implementation with the Main Extension (but no Security Extension) have a single pair of MPS/PSP Limit registers (non-secure)
  • ARMv8-M implementation with the Security Extension (but no Main Extension) have a single pair of MPS/PSP Limit registers (secure)
  • ARMv8-M implementation with the Main Extension and the Security Extension have two pairs of MPS/PSP Limit registers (secure and non-secure)

Design

Stack Pointer (SP)-limit-based protection could replace the MPU-based stack guards on ARMv8-M CPU with native SP limit checks:

  • Instead of re-configuring the MPU region at every context switch, to achieve thread stack protection, we can, alternatively, re-update the stack pointer limit registers with the updated values upon context switch.
  • Stack pointer limits will protect the current stacks during context stacking (exception entry and/or switch to Non-Secure state)
  • Stack protection based on stack limit registers will work for either security state, because the registers are banked.

We implement configure_builtin_stack_guard(), which is called during context switch, and re-adjusts the PSPLIM to the stack allocation pointer of the thread in the context of which we are switching to.
PSPLIM is, additionally, set to _main_stack during initialization, before jumping to the main_thread.

In addition to that:

  • As long as the Main Stack Pointer (MSP) is used solely in the interrupt stack, we can, now, protect the Interrupt stack, too, which is currently not protected (i.e. it is allowed to grow indefinitely) and:
    • corrupt memory below the stack
    • (in case of secure code) avoid memory leak to non-secure firmware, if stack crosses Non-Secure domain boundaries
    • (in case of non-secure code) avoid causing SecureFault, if stack crosses Secure domain boundaries

At initialization, upon configuring the _interrupt_stack, MSPLIM is set to the interrupts stack allocation pointer.


  • Stack guards via Stack Pointer limit checking do not require a reservation of an MPU guard region, thus, save some wasted memory space that should otherwise be kept as "trash" for thread stack overflow detection.

  • Special Note: Stack Pointer limit checking will be ignored in HardFault and NMI fault handlers, to allow for proper execution of the fault handlers (e.g. fault dump functionality). This has the following implications:

    • In Secure Firmware, the stack during HF and NMI may transit into non-secure region, if we place the Secure stack higher than non-secure regions. We should not do that.
    • In Non-Secure Firmware: the stack during HF and NMI may attempt to transit into secure region, if we place the Non-Secure stack directly above the Secure region. We should not do that. But even if we do, the secure stack will not be affected, but a SecureFault will be triggered.

@ioannisg ioannisg added the Feature label Mar 6, 2018

@ioannisg ioannisg moved this from In progress to In Review in Trusted Execution May 22, 2018

@ioannisg ioannisg moved this from In Review to Done in Trusted Execution Jun 15, 2018

@ioannisg ioannisg closed this Jun 15, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.