summaryrefslogtreecommitdiffstats
path: root/libc/bionic/pthread_create.cpp
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2015-03-29 00:03:55 -0400
committerDaniel Micay <danielmicay@gmail.com>2015-03-30 17:13:20 -0400
commit595752f623ae88f7e4193a6e531a0805f1c6c4dc (patch)
tree2a8d25e25b042f04146725c7a287619e2892940c /libc/bionic/pthread_create.cpp
parent203082b8217cd853eee510ad371b382701960610 (diff)
downloadbionic-595752f623ae88f7e4193a6e531a0805f1c6c4dc.zip
bionic-595752f623ae88f7e4193a6e531a0805f1c6c4dc.tar.gz
bionic-595752f623ae88f7e4193a6e531a0805f1c6c4dc.tar.bz2
add guard pages to the internal signal stacks
Signal handlers tend to be lean, but can still overflow the (tiny) stack. Change-Id: Ia21c6453d92a9f8d1536ad01ff26a1a84c05f8fb
Diffstat (limited to 'libc/bionic/pthread_create.cpp')
-rw-r--r--libc/bionic/pthread_create.cpp18
1 files changed, 12 insertions, 6 deletions
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 66632c4..179ae95 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -69,17 +69,23 @@ 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 = 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.
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ss.ss_sp, ss.ss_size, "thread signal stack");
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, stack_base, SIGNAL_STACK_SIZE, "thread signal stack");
}
}