From 8f6f1326baa9eb804790030e1cdb58fca2eecab6 Mon Sep 17 00:00:00 2001 From: HeatCrab Date: Mon, 2 Feb 2026 17:47:46 +0800 Subject: [PATCH] Add U-mode task isolation and fix self-termination U-mode tasks could previously control other tasks and had no way to properly terminate themselves. This adds permission checks to restrict task control syscalls to self-only operations and enables safe self-termination through the existing zombie task mechanism. --- kernel/syscall.c | 19 +++++++++---------- kernel/task.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/kernel/syscall.c b/kernel/syscall.c index 8ad87e0..c724ae9 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -278,8 +278,8 @@ int sys_task_spawn(void *task, int stack_size) static int _tcancel(int id) { - if (unlikely(id <= 0)) - return -EINVAL; + if (id <= 0 || (uint16_t) id != mo_task_id()) + return -EPERM; return mo_task_cancel(id); } @@ -316,8 +316,8 @@ int sys_tdelay(int ticks) static int _tsuspend(int id) { - if (unlikely(id <= 0)) - return -EINVAL; + if (id <= 0 || (uint16_t) id != mo_task_id()) + return -EPERM; return mo_task_suspend(id); } @@ -329,10 +329,9 @@ int sys_tsuspend(int id) static int _tresume(int id) { - if (unlikely(id <= 0)) - return -EINVAL; - - return mo_task_resume(id); + (void) id; + /* U-mode cannot resume any task; suspended task cannot call syscall */ + return -EPERM; } int sys_tresume(int id) @@ -342,8 +341,8 @@ int sys_tresume(int id) static int _tpriority(int id, int priority) { - if (unlikely(id <= 0)) - return -EINVAL; + if (id <= 0 || (uint16_t) id != mo_task_id()) + return -EPERM; return mo_task_priority(id, priority); } diff --git a/kernel/task.c b/kernel/task.c index 286e83e..e6f694d 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -992,9 +992,20 @@ int32_t mo_task_spawn_user(void *task_entry, uint16_t stack_size) int32_t mo_task_cancel(uint16_t id) { - if (id == 0 || id == mo_task_id()) + if (id == 0) return ERR_TASK_CANT_REMOVE; + /* Self-termination marks the task as zombie and yields to the scheduler. + * The dispatcher will reclaim resources after context switch completes. + */ + if (id == mo_task_id()) { + tcb_t *self = kcb->task_current->data; + self->state = TASK_ZOMBIE; + _yield(); + while (1) + ; + } + CRITICAL_ENTER(); list_node_t *node = find_task_node_by_id(id); if (!node) {