From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Renlord Date: Thu, 12 Sep 2019 14:51:51 +1000 Subject: [PATCH] add guard page(s) between static_tls and stack Signed-off-by: anupritaisno1 --- libc/bionic/pthread_create.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 121b26f82..31c553e25 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -201,9 +201,10 @@ int __init_thread(pthread_internal_t* thread) { ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) { const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout; - // Allocate in order: stack guard, stack, static TLS, guard page. + // Allocate in order: stack guard, stack, guard page, static TLS, guard page. size_t mmap_size; if (__builtin_add_overflow(stack_size, stack_guard_size, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; if (__builtin_add_overflow(mmap_size, layout.size(), &mmap_size)) return {}; if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; @@ -212,8 +213,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE); if (mmap_size < unaligned_size) return {}; - // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a - // read+write area in the middle. + // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out + // read+write areas for the stack and static TLS const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; char* const space = static_cast(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0)); if (space == MAP_FAILED) { @@ -223,13 +224,21 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si mmap_size, strerror(errno)); return {}; } - const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; - if (mprotect(space + stack_guard_size, - writable_size, - PROT_READ | PROT_WRITE) != 0) { + + if (mprotect(space + stack_guard_size, stack_size, PROT_READ | PROT_WRITE) != 0) { async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't mprotect R+W %zu-byte thread mapping region: %s", - writable_size, strerror(errno)); + stack_size, strerror(errno)); + munmap(space, mmap_size); + return {}; + } + + char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; + + if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %s", + layout.size(), strerror(errno)); munmap(space, mmap_size); return {}; } @@ -239,9 +248,9 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si result.mmap_size = mmap_size; result.mmap_base_unguarded = space + stack_guard_size; result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; - result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size(); + result.static_tls = static_tls_space; result.stack_base = space; - result.stack_top = result.static_tls; + result.stack_top = space + stack_guard_size + stack_size; return result; }