diff options
author | Yabin Cui <yabinc@google.com> | 2015-03-30 20:03:57 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-03-30 20:51:39 -0700 |
commit | ef115003012f61cf5539fdfeb201b98e4a92f610 (patch) | |
tree | d546925be11de056c9c2611fb75d91273cd10303 /libc/bionic | |
parent | 8225ad63fac7c5cc298884c101a344959b87dc39 (diff) | |
download | bionic-ef115003012f61cf5539fdfeb201b98e4a92f610.zip bionic-ef115003012f61cf5539fdfeb201b98e4a92f610.tar.gz bionic-ef115003012f61cf5539fdfeb201b98e4a92f610.tar.bz2 |
Revert "Revert "add guard pages to the internal signal stacks""
This reverts commit a3125fd1396a09a7fc4872dc4653f342150a3deb.
And Fix the prctl() problem that cause system crash.
Change-Id: Icc8d12d848cfba881a7984ca2827fd81be41f9fd
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/pthread_create.cpp | 17 | ||||
-rw-r--r-- | libc/bionic/pthread_exit.cpp | 2 | ||||
-rw-r--r-- | libc/bionic/pthread_internal.h | 3 |
3 files changed, 16 insertions, 6 deletions
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 66632c4..dbdb180 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -69,13 +69,20 @@ void __init_tls(pthread_internal_t* thread) { void __init_alternate_signal_stack(pthread_internal_t* thread) { // Create and set an alternate signal stack. - stack_t ss; - ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - if (ss.ss_sp != MAP_FAILED) { - ss.ss_size = SIGSTKSZ; + void* stack_base = mmap(NULL, SIGNAL_STACK_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (stack_base != MAP_FAILED) { + + // Create a guard page to catch stack overflows in signal handlers. + if (mprotect(stack_base, PAGE_SIZE, PROT_NONE) == -1) { + munmap(stack_base, SIGNAL_STACK_SIZE); + return; + } + stack_t ss; + ss.ss_sp = reinterpret_cast<uint8_t*>(stack_base) + PAGE_SIZE; + ss.ss_size = SIGNAL_STACK_SIZE - PAGE_SIZE; ss.ss_flags = 0; sigaltstack(&ss, NULL); - thread->alternate_signal_stack = ss.ss_sp; + thread->alternate_signal_stack = stack_base; // We can only use const static allocated string for mapped region name, as Android kernel // uses the string pointer directly when dumping /proc/pid/maps. diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp index 1de85f5..ceda931 100644 --- a/libc/bionic/pthread_exit.cpp +++ b/libc/bionic/pthread_exit.cpp @@ -87,7 +87,7 @@ void pthread_exit(void* return_value) { sigaltstack(&ss, NULL); // Free it. - munmap(thread->alternate_signal_stack, SIGSTKSZ); + munmap(thread->alternate_signal_stack, SIGNAL_STACK_SIZE); thread->alternate_signal_stack = NULL; } diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 2151e03..3b91e6a 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -130,6 +130,9 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void); */ #define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ) +/* Leave room for a guard page in the internally created signal stacks. */ +#define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE) + /* Needed by fork. */ __LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare(); __LIBC_HIDDEN__ extern void __bionic_atfork_run_child(); |