From bb3e7d27ff46a6e6808022a50c3c61f5ae8e925b Mon Sep 17 00:00:00 2001 From: Philippe Thierry Date: Thu, 4 Jun 2026 08:48:43 +0200 Subject: [PATCH 1/4] arm-psplim-support --- kernel/src/arch/asm-cortex-m/handler.c | 7 +++++++ kernel/src/managers/task/task_core.c | 22 ++++++++++++++++++++++ kernel/src/managers/task/task_core.h | 8 ++++++++ kernel/src/managers/task/task_init.c | 6 +++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/kernel/src/arch/asm-cortex-m/handler.c b/kernel/src/arch/asm-cortex-m/handler.c index 2a3697aa..50cd9f5f 100644 --- a/kernel/src/arch/asm-cortex-m/handler.c +++ b/kernel/src/arch/asm-cortex-m/handler.c @@ -339,6 +339,13 @@ stack_frame_t *Default_SubHandler(stack_frame_t *frame) /* clearing the sysreturn. next job is no more syscall-preempted */ mgr_task_clear_sysreturn(next); } +#if CONFIG_ARCH_ARM_ARMV8MML + /* ARMv8-M Mainline support PSPLIM register to detect stack overflow */ + size_t stack_limit = 0; + if (likely(mgr_task_get_stack_size(next, &stack_limit) == K_STATUS_OKAY)) { + asm volatile ("MRS %0, psplim_ns" : "=r" (stack_limit) ); + } +#endif return newframe; } diff --git a/kernel/src/managers/task/task_core.c b/kernel/src/managers/task/task_core.c index bf968709..71333886 100644 --- a/kernel/src/managers/task/task_core.c +++ b/kernel/src/managers/task/task_core.c @@ -90,6 +90,28 @@ size_t mgr_task_get_text_region_size(const task_meta_t *meta) /* got and data in flash are excluded (no need) */ } +/*@ + requires \valid(stack_limit); + assigns *stack_limit; +*/ +kstatus_t mgr_task_get_stack_size(const taskh_t h, size_t* stack_limit) +{ + kstatus_t status = K_ERROR_INVPARAM; + task_t *tsk = task_get_from_handle(h); + if (unlikely(tsk == NULL)) { + pr_err("invalid task handle!"); + goto err; + } + if (unlikely(stack_limit == NULL)) { + pr_err("invalid stack limit pointer!"); + goto err; + } + *stack_limit = tsk->stack_limit; + status = K_STATUS_OKAY; +err: + return status; +} + void task_dump_table(void) { #ifndef CONFIG_BUILD_TARGET_RELEASE diff --git a/kernel/src/managers/task/task_core.h b/kernel/src/managers/task/task_core.h index 12e1d6a9..9076ec49 100644 --- a/kernel/src/managers/task/task_core.h +++ b/kernel/src/managers/task/task_core.h @@ -128,13 +128,21 @@ typedef struct task { secure_bool_t sysretassigned; /**< a syscall has assigned a sysreturn */ Status sysreturn; /**< current job syscall return */ secure_bool_t has_respawned; /**< SECURE_TRUE if the task has been respawned */ + size_t stack_limit; /**< stack limit address, based on metadata info */ } task_t; kstatus_t task_set_job_layout(task_t * const tsk); +/*@ + assigns \nothing; + ensures \valid(\result); + */ task_t *task_get_table(void); +/*@ + assigns \nothing; + */ task_t *task_get_from_handle(taskh_t h); void task_dump_table(void); diff --git a/kernel/src/managers/task/task_init.c b/kernel/src/managers/task/task_init.c index f7cc9201..4c83fe44 100644 --- a/kernel/src/managers/task/task_init.c +++ b/kernel/src/managers/task/task_init.c @@ -254,7 +254,11 @@ kstatus_t task_do_initiate_localinfo(task_meta_t const * const meta, task_t *tas */ task_ctx->sp = mgr_task_initialize_sp(0UL, stack_top, (meta->s_text + meta->entrypoint_offset), meta->s_got); #endif - + if (unlikely(stack_top > meta->stack_size)) { + pr_err("security invalid stack size, stack top is above stack bottom"); + panic(PANIC_CONFIGURATION_MISMATCH); + } + task_ctx->stack_limit = stack_top - meta->stack_size; task_ctx->state = JOB_STATE_READY; task_ctx->sysretassigned = SECURE_FALSE; task_ctx->returncode = 0UL; From ae767e2eb6f8a4bd9f23e997ae179bf3936cea25 Mon Sep 17 00:00:00 2001 From: Philippe Thierry Date: Thu, 4 Jun 2026 09:02:39 +0200 Subject: [PATCH 2/4] fix: fixing invalid compare and contract --- kernel/src/managers/task/task_core.c | 13 +++++++++++-- kernel/src/managers/task/task_init.c | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/kernel/src/managers/task/task_core.c b/kernel/src/managers/task/task_core.c index 71333886..9a98aec2 100644 --- a/kernel/src/managers/task/task_core.c +++ b/kernel/src/managers/task/task_core.c @@ -91,8 +91,17 @@ size_t mgr_task_get_text_region_size(const task_meta_t *meta) } /*@ - requires \valid(stack_limit); - assigns *stack_limit; + assigns \nothing; + + behavior ok: + assumes stack_limit != \null; + assigns *stack_limit; + behavior err: + assumes stack_limit == \null; + assigns \nothing; + + complete behaviors; + disjoint behaviors; */ kstatus_t mgr_task_get_stack_size(const taskh_t h, size_t* stack_limit) { diff --git a/kernel/src/managers/task/task_init.c b/kernel/src/managers/task/task_init.c index 4c83fe44..d797f15f 100644 --- a/kernel/src/managers/task/task_init.c +++ b/kernel/src/managers/task/task_init.c @@ -254,8 +254,8 @@ kstatus_t task_do_initiate_localinfo(task_meta_t const * const meta, task_t *tas */ task_ctx->sp = mgr_task_initialize_sp(0UL, stack_top, (meta->s_text + meta->entrypoint_offset), meta->s_got); #endif - if (unlikely(stack_top > meta->stack_size)) { - pr_err("security invalid stack size, stack top is above stack bottom"); + if (unlikely(stack_top < meta->stack_size)) { + pr_err("security invalid stack size, not mappable "); panic(PANIC_CONFIGURATION_MISMATCH); } task_ctx->stack_limit = stack_top - meta->stack_size; From 4b72d7c7313b8178ff7e049cf8a3829a15b95170 Mon Sep 17 00:00:00 2001 From: Philippe Thierry Date: Thu, 4 Jun 2026 09:08:18 +0200 Subject: [PATCH 3/4] fixing invalid msr to psplim, moving to S mode --- kernel/src/arch/asm-cortex-m/handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/src/arch/asm-cortex-m/handler.c b/kernel/src/arch/asm-cortex-m/handler.c index 50cd9f5f..435c5426 100644 --- a/kernel/src/arch/asm-cortex-m/handler.c +++ b/kernel/src/arch/asm-cortex-m/handler.c @@ -343,7 +343,7 @@ stack_frame_t *Default_SubHandler(stack_frame_t *frame) /* ARMv8-M Mainline support PSPLIM register to detect stack overflow */ size_t stack_limit = 0; if (likely(mgr_task_get_stack_size(next, &stack_limit) == K_STATUS_OKAY)) { - asm volatile ("MRS %0, psplim_ns" : "=r" (stack_limit) ); + asm volatile ("MSR psplim, %0" : : "r" (stack_limit) ); } #endif return newframe; From ba26870e94f394305fc8586eb69d453fe7cd88ef Mon Sep 17 00:00:00 2001 From: Philippe Thierry Date: Thu, 4 Jun 2026 11:53:33 +0200 Subject: [PATCH 4/4] psplim: adding task new prototype export --- kernel/include/sentry/managers/task.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/kernel/include/sentry/managers/task.h b/kernel/include/sentry/managers/task.h index c740e882..d97cad80 100644 --- a/kernel/include/sentry/managers/task.h +++ b/kernel/include/sentry/managers/task.h @@ -214,5 +214,18 @@ kstatus_t mgr_task_local_ipc_iterate(taskh_t owner, taskh_t *peer, uint8_t *idx) */ secure_bool_t mgr_task_has_respawned(taskh_t t); +/** + * @brief return the limit address of the bottom of the stack + * + * This address is useful for hardwares that support stack overflow detection, + * as it can be used as a stack guard limit registers. + * + * @param t task handle + * @param stack_limit output parameter to store the stack limit address + * @return K_STATUS_OKAY if the stack limit has been successfully retrieved, + * K_ERROR_INVPARAM if the task handle is invalid or stack limit cannot be retrieved + */ +kstatus_t mgr_task_get_stack_size(const taskh_t h, size_t* stack_limit); + #endif/*!SECURITY_MANAGER_H*/