This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/20116] use after free in pthread_create
- From: "amakhalov at vmware dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Wed, 28 Sep 2016 20:29:20 +0000
- Subject: [Bug nptl/20116] use after free in pthread_create
- Auto-submitted: auto-generated
- References: <bug-20116-131@http.sourceware.org/bugzilla/>
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.