diff options
author | Gabe Black <gabeblack@google.com> | 2018-11-16 17:07:42 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-11-18 10:44:26 +0000 |
commit | 5bfde967dcbbfae884e343425da1fc069a9c4b86 (patch) | |
tree | 74238175235f5286797fe41edff55666974dde6b | |
parent | 040fabe2bd1d3e34dc2855b2b443af503b967c6b (diff) | |
download | gem5-5bfde967dcbbfae884e343425da1fc069a9c4b86.tar.xz |
base: Set up a guard page for fiber stacks.
This will help detect stack overflow for fibers.
Change-Id: Iff2b102120ec351709e495291d6bead597f8d10c
Reviewed-on: https://gem5-review.googlesource.com/c/14395
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r-- | src/base/fiber.cc | 39 | ||||
-rw-r--r-- | src/base/fiber.hh | 4 |
2 files changed, 31 insertions, 12 deletions
diff --git a/src/base/fiber.cc b/src/base/fiber.cc index eac1d9394..af63216da 100644 --- a/src/base/fiber.cc +++ b/src/base/fiber.cc @@ -33,7 +33,11 @@ #include <valgrind/valgrind.h> #endif +#include <sys/mman.h> +#include <unistd.h> + #include <cerrno> +#include <cstdio> #include <cstring> #include "base/logging.hh" @@ -71,28 +75,41 @@ Fiber::entryTrampoline() startingFiber->start(); } -Fiber::Fiber(size_t stack_size) : - link(primaryFiber()), - stack(stack_size ? new uint8_t[stack_size] : nullptr), - stackSize(stack_size), started(false), _finished(false) +Fiber::Fiber(size_t stack_size) : Fiber(primaryFiber(), stack_size) +{} + +Fiber::Fiber(Fiber *link, size_t stack_size) : + link(link), stack(nullptr), stackSize(stack_size), guardPage(nullptr), + guardPageSize(sysconf(_SC_PAGE_SIZE)), started(false), _finished(false) { + if (stack_size) { + guardPage = mmap(nullptr, guardPageSize + stack_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (guardPage == (void *)MAP_FAILED) { + perror("mmap"); + fatal("Could not mmap %d byte fiber stack.\n", stack_size); + } + stack = (void *)((uint8_t *)guardPage + guardPageSize); + if (mprotect(guardPage, guardPageSize, PROT_NONE)) { + perror("mprotect"); + fatal("Could not forbid access to fiber stack guard page."); + } + } #if HAVE_VALGRIND - valgrindStackId = VALGRIND_STACK_REGISTER(stack, stack + stack_size); + valgrindStackId = VALGRIND_STACK_REGISTER( + stack, (uint8_t *)stack + stack_size); #endif } -Fiber::Fiber(Fiber *link, size_t stack_size) : - link(link), stack(stack_size ? new uint8_t[stack_size] : nullptr), - stackSize(stack_size), started(false), _finished(false) -{} - Fiber::~Fiber() { panic_if(stack && _currentFiber == this, "Fiber stack is in use."); #if HAVE_VALGRIND VALGRIND_STACK_DEREGISTER(valgrindStackId); #endif - delete [] stack; + if (guardPage) + munmap(guardPage, guardPageSize + stackSize); } void diff --git a/src/base/fiber.hh b/src/base/fiber.hh index 3d82075f0..4d95e032b 100644 --- a/src/base/fiber.hh +++ b/src/base/fiber.hh @@ -106,8 +106,10 @@ class Fiber Fiber *link; // The stack for this context, or a nullptr if allocated elsewhere. - uint8_t *stack; + void *stack; size_t stackSize; + void *guardPage; + size_t guardPageSize; #if HAVE_VALGRIND unsigned valgrindStackId; #endif |