[Bug dynamic-link/13862] New: Reuse of cached stack can cause bounds overrun of thread DTV
paul at vineyardnetworks dot com
sourceware-bugzilla@sourceware.org
Fri Mar 16 22:47:00 GMT 2012
http://sourceware.org/bugzilla/show_bug.cgi?id=13862
Bug #: 13862
Summary: Reuse of cached stack can cause bounds overrun of
thread DTV
Product: glibc
Version: 2.14
Status: NEW
Severity: normal
Priority: P2
Component: dynamic-link
AssignedTo: unassigned@sourceware.org
ReportedBy: paul@vineyardnetworks.com
Classification: Unclassified
Created attachment 6290
--> http://sourceware.org/bugzilla/attachment.cgi?id=6290
Small program that demonstrates the issue
Platform: Linux/x86_64 (multiple versions including Ubuntu 10, 12, Fedora core
14, Centos 5.5+)
GLIBC versions: tested with 2.7, 2.9, 2.11, 2.14 built from official source
In a program satisfying the conditions listed below, reusing a cached stack
causes a bounds overrun of the thread's DTV structure, leading to a probable
crash. The _dl_allocate_tls_init function re-initializes the dtv based on the
current slotinfo_list, however it is possible for the dtv to be smaller than
the highest module id loaded. When this happens the function will write over
memory outside of the dtv, leading to unpredictable behavior and an eventual
crash.
See proposed fix below and attached test-case for repro.
Conditions needed:
The use of a relatively large number of dynamic libraries, loaded at runtime
using dlopen
The use of thread-local-storage within those libraries
A thread exiting prior to the number of loaded libraries increasing a
significant amount, followed by a new thread being created after the number of
libraries has increased.
Example Valgrind output:
==27966== Invalid write of size 8
==27966== at 0x4010A7A: _dl_allocate_tls_init (dl-tls.c:418)
==27966== by 0x4E35294: pthread_create@@GLIBC_2.2.5 (allocatestack.c:252)
followed by:
==27966== Address 0x5b4e6d0 is 0 bytes after a block of size 304 alloc'd
==27966== at 0x4C26D85: calloc (vg_replace_malloc.c:566)
==27966== by 0x4010439: allocate_dtv (dl-tls.c:297)
==27966== by 0x4010B4D: _dl_allocate_tls (dl-tls.c:461)
==27966== by 0x4E357E9: pthread_create@@GLIBC_2.2.5 (allocatestack.c:575)
Proposed fix:
*** dl-tls.c 2011-05-30 21:12:33.000000000 -0700
--- ../../glibc-2.14.orig/elf/dl-tls.c 2012-03-13 11:29:27.172794002 -0700
***************
*** 406,411 ****
--- 406,415 ----
/* Unused entry. */
continue;
+ /* make sure we don't overrun the currently allocated dtv */
+ if (map->l_tls_modid >= dtv[-1].counter)
+ continue;
+
/* Keep track of the maximum generation number. This might
not be the generation counter. */
maxgen = MAX (maxgen, listp->slotinfo[cnt].gen);
***************
*** 599,605 ****
{
/* If this modid was used at some point the memory
might still be allocated. */
! if (! dtv[total + cnt].pointer.is_static
&& dtv[total + cnt].pointer.val != TLS_DTV_UNALLOCATED)
{
free (dtv[total + cnt].pointer.val);
--- 603,609 ----
{
/* If this modid was used at some point the memory
might still be allocated. */
! if (total + cnt < dtv[-1].counter && !dtv[total +
cnt].pointer.is_static
&& dtv[total + cnt].pointer.val != TLS_DTV_UNALLOCATED)
{
free (dtv[total + cnt].pointer.val);
Reproduction/test case attached.
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the Glibc-bugs
mailing list