Skip to content

Commit

Permalink
arch: arm: make priv stack guard programming similar to normal guard
Browse files Browse the repository at this point in the history
This commit aligns the programming of the privileged stack MPU
guard with that of the default stack guard (i.e of supervisor
threads). In particular:
- the guard is programmed BELOW the address indicated in
  arch.priv_stack_start; it is, therefore, similar to the
  default guard that is programmed BELOW stack_info.start.
  An ASSERT is added to confirm that the guard is programmed
  inside the thread privilege stack area.
- the stack fail check is updated accordningly
- arch.priv_stack_start is adjusted in arch_userspace_enter(),
  to make sure we account for a (possible) guard requirement,
  that is, if building with CONFIG_MPU_STACK_GUARD=y.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
  • Loading branch information
ioannisg authored and andrewboie committed Jun 24, 2019
1 parent f15c12d commit 639eb76
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
6 changes: 5 additions & 1 deletion arch/arm/core/cortex_m/mpu/arm_core_mpu.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ void z_arch_configure_dynamic_mpu_regions(struct k_thread *thread)
u32_t guard_start; u32_t guard_start;
#if defined(CONFIG_USERSPACE) #if defined(CONFIG_USERSPACE)
if (thread->arch.priv_stack_start) { if (thread->arch.priv_stack_start) {
guard_start = thread->arch.priv_stack_start; guard_start = thread->arch.priv_stack_start -
MPU_GUARD_ALIGN_AND_SIZE;
__ASSERT((u32_t)&z_priv_stacks_ram_start <= guard_start,
"Guard start: (0x%x) below privilege stacks boundary: (0x%x)",
guard_start, (u32_t)&z_priv_stacks_ram_start);
} else { } else {
guard_start = thread->stack_info.start - guard_start = thread->stack_info.start -
MPU_GUARD_ALIGN_AND_SIZE; MPU_GUARD_ALIGN_AND_SIZE;
Expand Down
13 changes: 10 additions & 3 deletions arch/arm/core/thread.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ FUNC_NORETURN void z_arch_user_mode_enter(k_thread_entry_t user_entry,
/* Set up privileged stack before entering user mode */ /* Set up privileged stack before entering user mode */
_current->arch.priv_stack_start = _current->arch.priv_stack_start =
(u32_t)z_priv_stack_find(_current->stack_obj); (u32_t)z_priv_stack_find(_current->stack_obj);
#if defined(CONFIG_MPU_STACK_GUARD)
/* Stack guard area reserved at the bottom of the thread's
* privileged stack. Adjust the available (writable) stack
* buffer area accordingly.
*/
_current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE;
#endif /* CONFIG_MPU_STACK_GUARD */


z_arm_userspace_enter(user_entry, p1, p2, p3, z_arm_userspace_enter(user_entry, p1, p2, p3,
(u32_t)_current->stack_info.start, (u32_t)_current->stack_info.start,
Expand Down Expand Up @@ -265,11 +272,11 @@ u32_t z_check_thread_stack_fail(const u32_t fault_addr, const u32_t psp)
if ((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0) { if ((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0) {
/* User thread in privilege mode */ /* User thread in privilege mode */
if (IS_MPU_GUARD_VIOLATION( if (IS_MPU_GUARD_VIOLATION(
thread->arch.priv_stack_start, thread->arch.priv_stack_start -
MPU_GUARD_ALIGN_AND_SIZE,
fault_addr, psp)) { fault_addr, psp)) {
/* Thread's privilege stack corruption */ /* Thread's privilege stack corruption */
return thread->arch.priv_stack_start + return thread->arch.priv_stack_start;
MPU_GUARD_ALIGN_AND_SIZE;
} }
} else { } else {
if (psp < (u32_t)thread->stack_obj) { if (psp < (u32_t)thread->stack_obj) {
Expand Down

0 comments on commit 639eb76

Please sign in to comment.