This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/20116] use after free in pthread_create


https://sourceware.org/bugzilla/show_bug.cgi?id=20116

--- Comment #5 from Alexey Makhalov <amakhalov at vmware dot com> ---
This is an issue (use after free) of detached pthreads.
It is a regression. glibc-2.19 works well.

Found in glibc-2.22.

Test app to repro the issue is attached. Reproducible in Ubuntu-16.04 and
Photon-1.0

$ cc -pthread -g -Wall -o test_threads test_threads.c
$ ./test_threads
.................................Segmentation fault (core dumped)
$ gdb ./test_threads core.101787
GNU gdb (GDB) 7.10.1
...
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>,
start_routine=<optimized out>,
    arg=<optimized out>) at pthread_create.c:704

704 if (pd->stopped_start)
[Current thread is 1 (Thread 0x7f86b8e41700 (LWP 101787))]
(gdb) bt
#0 __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>,
start_routine=<optimized out>,
    arg=<optimized out>) at pthread_create.c:704
#1 0x0000000000400a6c in main (argc=1, argv=0x7ffe3f5d25b8) at
test_threads.c:56
(gdb) p pd
$1 = (struct pthread *) 0x7f86b5c54700
(gdb) p *pd
Cannot access memory at address 0x7f86b5c54700


Also, valgrind detects an error here (pthread_create.c:704):
$ valgrind ./test_threads
==55731== Memcheck, a memory error detector
==55731== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==55731== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==55731== Command: ./test_threads
==55731==
==55731== Invalid read of size 1
==55731== at 0x4E3BC17: pthread_create@@GLIBC_2.2.5 (pthread_create.c:704)
==55731== by 0x400A8B: main (in /root/test_threads)
==55731== Address 0xd21ad13 is not stack'd, malloc'd or (recently) free'd
==55731==


Short description:
1) pthread_create function allocates stack for the thread.
2) Then it calls create_thread (clone syscall). If thread is detached its stack
will be reallocated immediately on thread routine exit.
3) After create_thread, it analyzes some data from thread stack – which might
be freed in between (If pthread function is short enough).


More details:

__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg) {
        …
          struct pthread *pd = NULL;
          int err = ALLOCATE_STACK (iattr, &pd);                               
        <- thread stack allocation
        …
          pd->start_routine = start_routine;
         pd->arg = arg;
       …
           retval = create_thread (pd, iattr, false, STACK_VARIABLES_ARGS,     
        <-clone syscall with a start function START_THREAD_DEFN
                            &thread_ran);

         if (__glibc_unlikely (retval != 0))
           {
           …
           }
         else
           {
             if (pd->stopped_start)                                            
        <- USE AFTER FREE!
        …
   }
}

START_THREAD_DEFN                                                              
<-thread starter function (wrapper)
{
…
      /* Run the code the user provided.  */
#ifdef CALL_THREAD_FCT
      THREAD_SETMEM (pd, result, CALL_THREAD_FCT (pd));
#else
      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));                 
<- start real start_routine (which is short 1000 cycles in Jonathans example)
#endif
…
  /* If the thread is detached free the TCB.  */
  if (IS_DETACHED (pd))
    /* Free the TCB.  */
    __free_tcb (pd);                                                           
<- IT WILL DEALLOCATE A STACK
…
}


Proposed patch is to use local variable instead of accessing thread stack to
get stopped_start flag.

Patch is attached.

Thanks,
--Alexey

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]