diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-12-20 11:20:54 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-12-20 11:48:47 -0800 |
| commit | 784713ec683c7cce0a1d4aa712a376317384d62c (patch) | |
| tree | d8063109957b61abc274df5fda54c30273e45eb2 /src/rt/rust_task.cpp | |
| parent | 4475ec863dd6c00eba67bc8111ce5fbe72409c9e (diff) | |
| download | rust-784713ec683c7cce0a1d4aa712a376317384d62c.tar.gz rust-784713ec683c7cce0a1d4aa712a376317384d62c.zip | |
rt: Add a canary value to the end of every stack
Check it on upcall entry and exit, and on stack deletion
Diffstat (limited to 'src/rt/rust_task.cpp')
| -rw-r--r-- | src/rt/rust_task.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
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++ |
