From 784713ec683c7cce0a1d4aa712a376317384d62c Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 20 Dec 2011 11:20:54 -0800 Subject: rt: Add a canary value to the end of every stack Check it on upcall entry and exit, and on stack deletion --- src/rt/rust_task.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/rt/rust_task.cpp') diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 23bd6647a04..125a2900ca0 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -49,6 +49,12 @@ #endif #endif +// A value that goes at the end of the stack and must not be touched +const uint8_t stack_canary[] = {0xAB, 0xCD, 0xAB, 0xCD, + 0xAB, 0xCD, 0xAB, 0xCD, + 0xAB, 0xCD, 0xAB, 0xCD, + 0xAB, 0xCD, 0xAB, 0xCD}; + // Stack size size_t g_custom_min_stack_size = 0; @@ -95,7 +101,8 @@ config_valgrind_stack(stk_seg *stk) { // old stack segments, since the act of popping the stack previously // caused valgrind to consider the whole thing inaccessible. size_t sz = stk->end - (uintptr_t)&stk->data[0]; - VALGRIND_MAKE_MEM_UNDEFINED(stk->data, sz); + VALGRIND_MAKE_MEM_UNDEFINED(stk->data + sizeof(stack_canary), + sz - sizeof(stack_canary)); #endif } @@ -110,6 +117,18 @@ free_stk(rust_task *task, stk_seg *stk) { task->free(stk); } +static void +add_stack_canary(stk_seg *stk) { + memcpy(stk->data, stack_canary, sizeof(stack_canary)); + assert(sizeof(stack_canary) == 16 && "Stack canary was not the expected size"); +} + +static void +check_stack_canary(stk_seg *stk) { + assert(!memcmp(stk->data, stack_canary, sizeof(stack_canary)) + && "Somebody killed the canary"); +} + static stk_seg* new_stk(rust_scheduler *sched, rust_task *task, size_t requested_sz) { @@ -151,6 +170,7 @@ new_stk(rust_scheduler *sched, rust_task *task, size_t requested_sz) stk_seg *stk = (stk_seg *)task->malloc(sz, "stack"); LOGPTR(task->sched, "new stk", (uintptr_t)stk); memset(stk, 0, sizeof(stk_seg)); + add_stack_canary(stk); stk->prev = NULL; stk->next = task->stk; stk->end = (uintptr_t) &stk->data[rust_stk_sz + RED_ZONE_SIZE]; @@ -165,6 +185,7 @@ static void del_stk(rust_task *task, stk_seg *stk) { assert(stk == task->stk && "Freeing stack segments out of order!"); + check_stack_canary(stk); task->stk = stk->next; @@ -784,6 +805,11 @@ rust_task::on_rust_stack() { return sp_in_stk_seg(get_sp(), stk); } +void +rust_task::check_stack_canary() { + ::check_stack_canary(stk); +} + // // Local Variables: // mode: C++ -- cgit 1.4.1-3-g733a5