Index: lib/libpthread/pthread.c =================================================================== RCS file: /cvsroot/src/lib/libpthread/pthread.c,v retrieving revision 1.125.4.1 diff -p -u -r1.125.4.1 pthread.c --- lib/libpthread/pthread.c 7 May 2012 03:12:33 -0000 1.125.4.1 +++ lib/libpthread/pthread.c 2 Dec 2012 18:50:03 -0000 @@ -1274,22 +1274,32 @@ pthread__stackid_setup(void *base, size_ { pthread_t t; void *redaddr; - size_t pagesize; + size_t pagesize, bytes_needed; int ret; t = base; pagesize = (size_t)sysconf(_SC_PAGESIZE); + bytes_needed = roundup(sizeof(*t), pagesize); + + if (pagesize >= size) + return ENOMEM; + if (bytes_needed >= (size - pagesize)) + return ENOMEM; /* * Put a pointer to the pthread in the bottom (but * redzone-protected section) of the stack. + * + * XXX If the stack grows up, the pthread is *not* + * protected by the redzone. */ - redaddr = STACK_SHRINK(STACK_MAX(base, size), pagesize); - t->pt_stack.ss_size = size - 2 * pagesize; + t->pt_stack.ss_size = size - bytes_needed - pagesize; #ifdef __MACHINE_STACK_GROWS_UP - t->pt_stack.ss_sp = (char *)(void *)base + pagesize; + redaddr = STACK_SHRINK(STACK_MAX(base, size), pagesize); + t->pt_stack.ss_sp = (char *)(void *)base + bytes_needed; #else - t->pt_stack.ss_sp = (char *)(void *)base + 2 * pagesize; + redaddr = STACK_SHRINK(STACK_MAX(base, size), bytes_needed); + t->pt_stack.ss_sp = (char *)(void *)base + bytes_needed + pagesize; #endif /* Protect the next-to-bottom stack page as a red zone. */ ret = mprotect(redaddr, pagesize, PROT_NONE);