Skip to content

Commit 8f6f132

Browse files
committed
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.
1 parent d21ba4d commit 8f6f132

2 files changed

Lines changed: 21 additions & 11 deletions

File tree

kernel/syscall.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ int sys_task_spawn(void *task, int stack_size)
278278

279279
static int _tcancel(int id)
280280
{
281-
if (unlikely(id <= 0))
282-
return -EINVAL;
281+
if (id <= 0 || (uint16_t) id != mo_task_id())
282+
return -EPERM;
283283

284284
return mo_task_cancel(id);
285285
}
@@ -316,8 +316,8 @@ int sys_tdelay(int ticks)
316316

317317
static int _tsuspend(int id)
318318
{
319-
if (unlikely(id <= 0))
320-
return -EINVAL;
319+
if (id <= 0 || (uint16_t) id != mo_task_id())
320+
return -EPERM;
321321

322322
return mo_task_suspend(id);
323323
}
@@ -329,10 +329,9 @@ int sys_tsuspend(int id)
329329

330330
static int _tresume(int id)
331331
{
332-
if (unlikely(id <= 0))
333-
return -EINVAL;
334-
335-
return mo_task_resume(id);
332+
(void) id;
333+
/* U-mode cannot resume any task; suspended task cannot call syscall */
334+
return -EPERM;
336335
}
337336

338337
int sys_tresume(int id)
@@ -342,8 +341,8 @@ int sys_tresume(int id)
342341

343342
static int _tpriority(int id, int priority)
344343
{
345-
if (unlikely(id <= 0))
346-
return -EINVAL;
344+
if (id <= 0 || (uint16_t) id != mo_task_id())
345+
return -EPERM;
347346

348347
return mo_task_priority(id, priority);
349348
}

kernel/task.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,9 +992,20 @@ int32_t mo_task_spawn_user(void *task_entry, uint16_t stack_size)
992992

993993
int32_t mo_task_cancel(uint16_t id)
994994
{
995-
if (id == 0 || id == mo_task_id())
995+
if (id == 0)
996996
return ERR_TASK_CANT_REMOVE;
997997

998+
/* Self-termination marks the task as zombie and yields to the scheduler.
999+
* The dispatcher will reclaim resources after context switch completes.
1000+
*/
1001+
if (id == mo_task_id()) {
1002+
tcb_t *self = kcb->task_current->data;
1003+
self->state = TASK_ZOMBIE;
1004+
_yield();
1005+
while (1)
1006+
;
1007+
}
1008+
9981009
CRITICAL_ENTER();
9991010
list_node_t *node = find_task_node_by_id(id);
10001011
if (!node) {

0 commit comments

Comments
 (0)