On Tue, Dec 01, 2020 at 06:12:32PM +0100, Sebastien Marie wrote:
> Hi,
>
> I have a random segfault while using threads with custom stack.
sorry, I omitted to mention some elements (thanks deraadt@):
dmesg contains such lines:
[test-thread]79782/462309 sp=6a5e0e4df18 inside 6a5e0e4d000-6a5e0e4e000: not
MAP_STACK
the segfault is due to the use of the memory which isn't a stack.
> In short, I am doing:
> - allocate a stack space for the thread
> - create a thread (with custom stack using pthread_attr_setstack())
> - join the thread
> - free the allocated stack
> - create a new thread, etc...
>
> If I remove the fact to free the allocate stack once done, it seems
> fine (but reach ENOMEM after a while).
>
> I am suspecting some state corruption or stack reuse, but I can't find
> where for now. Or am I doing bad thing and I shouldn't deallocate the
> stack at his place ?
>
>
> Here a simple reproducer in C:
>
> $ cat test-thread.c
>
> #include <sys/mman.h>
>
> #include <err.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> void *
> start(void *arg)
> {
> return arg;
> }
>
> void
> thread_spawn(pthread_t *thread)
> {
> pthread_attr_t attr;
> void *stack;
>
> /*
> * allocate a stack (no need of MAP_STACK:
> * pthread_attr_setstack will set it)
> */
> stack = mmap(NULL, PTHREAD_STACK_MIN, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_ANON, -1, 0);
> if (stack == MAP_FAILED)
> err(EXIT_FAILURE, "mmap");
>
> /* initialize the attr */
> if (pthread_attr_init(&attr) != 0)
> err(EXIT_FAILURE, "pthread_attr_init");
>
> if (pthread_attr_setstack(&attr, stack, PTHREAD_STACK_MIN) != 0)
> err(EXIT_FAILURE, "pthread_attr_setstack");
>
> /*
> * create the thread, and pass the stack address as argument
> * (to retreive it once done)
> */
> if (pthread_create(thread, &attr, start, stack) != 0)
> err(EXIT_FAILURE, "pthread_create");
> }
>
> void
> thread_wait(pthread_t *thread)
> {
> void *retval = NULL;
>
> /* join the thread and retreive the stack address */
> if (pthread_join(*thread, &retval) != 0)
> err(EXIT_FAILURE, "pthread_join");
>
> /* we are done, unmap the stack address */
> if (munmap(retval, PTHREAD_STACK_MIN) != 0)
> err(EXIT_FAILURE, "munmap");
> }
>
> int
> main(int argc, char *argv[])
> {
> while (1) {
> pthread_t thread;
>
> thread_spawn(&thread);
> thread_wait(&thread);
> }
>
> return EXIT_SUCCESS;
> }
>
>
> $ cc -Wall test-thread.c -lpthread -o test-thread
> $ ./test-thread
> Segmentation fault (core dumped)
>
>
>
> Thanks.
> --
> Sebastien Marie
--
Sebastien Marie