diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index a4bd054c7..5389f144f 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -162,15 +162,16 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp, } // Mapped space(or user allocated stack) is used for: - // thread_internal_t + // pthread_internal_t // thread stack (including guard page) - stack_top -= sizeof(pthread_internal_t); + + // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary. + stack_top = reinterpret_cast( + (reinterpret_cast(stack_top) - sizeof(pthread_internal_t)) & ~0xf); + pthread_internal_t* thread = reinterpret_cast(stack_top); attr->stack_size = stack_top - reinterpret_cast(attr->stack_base); - // No need to check stack_top alignment. The size of pthread_internal_t is 16-bytes aligned, - // and user allocated stack is guaranteed by pthread_attr_setstack. - thread->mmap_size = mmap_size; thread->attr = *attr; __init_tls(thread); diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 538e0daaf..13964c2d8 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -103,7 +103,7 @@ struct pthread_internal_t { */ #define __BIONIC_DLERROR_BUFFER_SIZE 512 char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE]; -} __attribute__((aligned(16))); // Align it as thread stack top below it should be aligned. +}; __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list); __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);