Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/sys/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ typedef struct tcb {

/* Real-time Scheduling Support */
void *rt_prio; /* Opaque pointer for custom real-time scheduler hook */

/* Stack Protection */
uint32_t canary; /* Random stack canary for overflow detection */
} tcb_t;

/* Kernel Control Block (KCB)
Expand Down
7 changes: 7 additions & 0 deletions kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ int32_t main(void)
printf("Heap initialized, %u bytes available\n",
(unsigned int) (size_t) &_heap_size);

/* Seed PRNG with hardware entropy for stack canary randomization.
* Combine cycle counter (mcycle) and us timer for unpredictability. This
* prevents fixed canary values across boots.
*/
uint32_t entropy = read_csr(mcycle) ^ (uint32_t) _read_us();
srand(entropy);

/* Initialize deferred logging system.
* Must be done after heap init but before app_main() to ensure
* application tasks can use thread-safe printf.
Expand Down
23 changes: 13 additions & 10 deletions kernel/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include <hal.h>
#include <lib/libc.h>
#include <lib/queue.h>
#include <sys/task.h>

Expand Down Expand Up @@ -41,10 +42,6 @@ static volatile uint32_t timer_work_generation = 0; /* counter for coalescing */
/* Stack canary checking frequency - check every N context switches */
#define STACK_CHECK_INTERVAL 32

/* Magic number written to both ends of a task's stack for corruption detection.
*/
#define STACK_CANARY 0x33333333U

/* Stack check counter for periodic validation (reduces overhead). */
static uint32_t stack_check_counter = 0;
#endif /* CONFIG_STACK_PROTECTION */
Expand Down Expand Up @@ -153,12 +150,12 @@ static void task_stack_check(void)
uint32_t *hi_canary_ptr = (uint32_t *) ((uintptr_t) self->stack +
self->stack_sz - sizeof(uint32_t));

if (unlikely(*lo_canary_ptr != STACK_CANARY ||
*hi_canary_ptr != STACK_CANARY)) {
if (unlikely(*lo_canary_ptr != self->canary ||
*hi_canary_ptr != self->canary)) {
printf("\n*** STACK CORRUPTION: task %u base=%p size=%u\n", self->id,
self->stack, (unsigned int) self->stack_sz);
printf(" Canary values: low=0x%08x, high=0x%08x (expected 0x%08x)\n",
*lo_canary_ptr, *hi_canary_ptr, STACK_CANARY);
*lo_canary_ptr, *hi_canary_ptr, self->canary);
panic(ERR_STACK_CHECK);
}
}
Expand Down Expand Up @@ -544,10 +541,16 @@ static bool init_task_stack(tcb_t *tcb, size_t stack_size)
}

#if CONFIG_STACK_PROTECTION
/* Only initialize essential parts to reduce overhead */
*(uint32_t *) stack = STACK_CANARY;
/* Generate random canary for this task */
tcb->canary = (uint32_t) random();
/* Ensure canary is never zero */
if (tcb->canary == 0)
tcb->canary = 0xDEADBEEFU;

/* Write canary to both ends of stack */
*(uint32_t *) stack = tcb->canary;
*(uint32_t *) ((uintptr_t) stack + stack_size - sizeof(uint32_t)) =
STACK_CANARY;
tcb->canary;
#endif

tcb->stack = stack;
Expand Down