refactor(core): simplify reconfiguration of MPU for systask
What changed, and why it matters
This commit is a code cleanup: it replaces several copies of the same small block of code with a single helper function called systask_set_mpu(). The helper does exactly the same thing as the old repeated code—configures memory protection for an applet if one is attached, and does nothing otherwise. There is no change in behavior or security boundary.
No security action required; treat as normal refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The refactor centralizes MPU applet-layout restoration into a new void systask_set_mpu(systask_t* task) helper. It is called from elf_loader.c during applet unload/loading cleanup, from systask.c during task call setup, register setting, and PendSV context-switch save/restore, and from sysevent.c when polling events. The helper is guarded by #ifdef KERNEL and checks task->applet != NULL before calling mpu_set_active_applet(&applet->layout). This is a pure deduplication with no functional change.
Changed components
core/embed/io/app_loader/stm32/elf_loader.ccore/embed/sys/task/inc/sys/systask.hcore/embed/sys/task/stm32/systask.ccore/embed/sys/task/sysevent.cInspect captured patch +27 / −31
diff --git a/core/embed/io/app_loader/stm32/elf_loader.c b/core/embed/io/app_loader/stm32/elf_loader.c
index 637fe2d0..79588759 100644
--- a/core/embed/io/app_loader/stm32/elf_loader.c
+++ b/core/embed/io/app_loader/stm32/elf_loader.c
@@ -303,12 +303,8 @@ static void elf_unload_cb(applet_t* applet) {
// Clear applet data segment
mpu_set_active_applet(&applet->layout);
memset(ram_start, 0, ram_size);
-
- systask_t* active_task = systask_active();
- if (active_task->applet != NULL) {
- applet_t* active_applet = (applet_t*)active_task->applet;
- mpu_set_active_applet(&active_applet->layout);
- }
+ // Recover MPU state for the active task
+ systask_set_mpu(systask_active());
// Free applet RAM
app_arena_free(ram_start);
@@ -449,11 +445,7 @@ cleanup:
}
// Recover MPU state for the active task
- systask_t* active_task = systask_active();
- if (active_task->applet != NULL) {
- applet_t* applet = (applet_t*)active_task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(systask_active());
return retval;
}
diff --git a/core/embed/sys/task/inc/sys/systask.h b/core/embed/sys/task/inc/sys/systask.h
index 8f68f8b1..3e838055 100644
--- a/core/embed/sys/task/inc/sys/systask.h
+++ b/core/embed/sys/task/inc/sys/systask.h
@@ -258,6 +258,16 @@ bool systask_init(systask_t* task, uint32_t stack_base, uint32_t stack_size,
*/
bool systask_is_alive(const systask_t* task);
+/**
+ * @brief Sets the MPU configuration for the given task
+ *
+ * The function configures the MPU regions according to the task's
+ * associated applet layout. Does nothing if the task has no associated applet.
+ *
+ * @param task Pointer to the task.
+ */
+void systask_set_mpu(systask_t* task);
+
/**
* @brief Pushes data onto the stack of the task
*
diff --git a/core/embed/sys/task/stm32/systask.c b/core/embed/sys/task/stm32/systask.c
index 2d935739..23644a8d 100644
--- a/core/embed/sys/task/stm32/systask.c
+++ b/core/embed/sys/task/stm32/systask.c
@@ -190,6 +190,15 @@ bool systask_init(systask_t* task, uint32_t stack_base, uint32_t stack_size,
systask_id_t systask_id(const systask_t* task) { return task->id; }
+#ifdef KERNEL
+void systask_set_mpu(systask_t* task) {
+ if (task->applet != NULL) {
+ applet_t* applet = (applet_t*)task->applet;
+ mpu_set_active_applet(&applet->layout);
+ }
+}
+#endif // KERNEL
+
uint32_t* systask_push_data(systask_t* task, const void* data, size_t size) {
if (task->sp < task->sp_lim) {
// Stack overflow
@@ -219,10 +228,7 @@ void systask_pop_data(systask_t* task, size_t size) { task->sp += size; }
bool systask_push_call(systask_t* task, void* entrypoint, uintptr_t arg1,
uintptr_t arg2, uintptr_t arg3) {
#ifdef KERNEL
- if (task->applet != NULL) {
- applet_t* applet = (applet_t*)task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(task);
#endif
uint32_t original_sp = task->sp;
@@ -316,10 +322,7 @@ void systask_set_r0r1(systask_t* task, uint32_t r0, uint32_t r1) {
}
#ifdef KERNEL
- if (task->applet != NULL) {
- applet_t* applet = (applet_t*)task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(task);
#endif
stack[STK_FRAME_R0] = r0;
@@ -581,10 +584,7 @@ __attribute((no_stack_protector, used)) static uint32_t scheduler_pendsv(
if (prev_task->tls_size != 0) {
#ifdef KERNEL
- if (prev_task->applet != NULL) {
- applet_t* applet = (applet_t*)prev_task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(prev_task);
#endif
// Save the TLS of the previous task
@@ -610,10 +610,7 @@ __attribute((no_stack_protector, used)) static uint32_t scheduler_pendsv(
mpu_reconfig(next_task->mpu_mode);
#ifdef KERNEL
- if (next_task->applet != NULL) {
- applet_t* applet = (applet_t*)next_task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(next_task);
if (next_task->tls_size != 0) {
// Restore the TLS of the next task
diff --git a/core/embed/sys/task/sysevent.c b/core/embed/sys/task/sysevent.c
index 70d8d218..a0431527 100644
--- a/core/embed/sys/task/sysevent.c
+++ b/core/embed/sys/task/sysevent.c
@@ -270,10 +270,7 @@ void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled,
events_processed = true;
systask_t *task = poller->task;
#if defined(KERNEL) && !defined(TREZOR_EMULATOR)
- if (task->applet != NULL) {
- applet_t *applet = (applet_t *)task->applet;
- mpu_set_active_applet(&applet->layout);
- }
+ systask_set_mpu(task);
#endif
if (poller->signalled_arg != NULL) {
*poller->signalled_arg = poller->signalled;
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.