Bug 10069 - __pthread_init_static_tls (nptl/allocatestack.c) writes out of bounds of dtv array
Summary: __pthread_init_static_tls (nptl/allocatestack.c) writes out of bounds of dtv ...
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: 2.4
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-04-14 16:34 UTC by Tom Aernoudt
Modified: 2014-07-01 07:18 UTC (History)
2 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments
testcase to reproduce the problem (1.83 KB, text/plain)
2009-04-14 16:37 UTC, Tom Aernoudt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Aernoudt 2009-04-14 16:34:28 UTC
When a multi-threaded executable dynamically loads 15 (or more) shared libraries
that use TLS and are compiled without -fPIC the function
__pthread_init_static_tls (called from dlopen) will write out of bounds of the
dtv array.

The dtv array has initially a size of 16. The module index (map->l_tls_modid)
used as an index in the dtv array is incremented after every dlopen. But the dtv
array is never reallocated.

If the shared library is compiled with -fPIC the dtv array is reallocated from
__tls_get_addr and everything seems to work correctly.

I could verify that the following glibc versions have the problem:
- glibc-2.3.4
- glibc-2.3.5
- glibc-2.4

I could not verify (yet) if glibc-2.8 or the cvs version still have the problem.

Configure:
> ../glibc-2.4/configure --prefix=/usr/users/aernoudt/2/local/glibc-2.4
--enable-add-ons 

Kernel:
> uname -a
Linux tux13 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386
GNU/Linux

gcc version:
> gcc -v
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

ld version:
> ld -v
GNU ld version 2.15.92.0.2 20040927

Valgrind error:
==10407== Invalid write of size 4
==10407==    at 0x4030FF1: __pthread_init_static_tls (allocatestack.c:941)
==10407==    by 0x400F9AC: dl_open_worker (dl-open.c:452)
==10407==    by 0x400C0E3: _dl_catch_error (dl-error.c:178)
==10407==    by 0x400FB9B: _dl_open (dl-open.c:549)
==10407==    by 0x4027CFB: dlopen_doit (dlopen.c:66)
==10407==    by 0x400C0E3: _dl_catch_error (dl-error.c:178)
==10407==    by 0x4028260: _dlerror_run (dlerror.c:164)
==10407==    by 0x4027D7C: dlopen@@GLIBC_2.1 (dlopen.c:87)
==10407==    by 0x8048E1A: main (main.cpp:43)
==10407==  Address 0x4b710b8 is 0 bytes after a block of size 144 alloc'd
==10407==    at 0x401FC3E: calloc (vg_replace_malloc.c:397)
==10407==    by 0x400E49B: allocate_dtv (dl-tls.c:304)
==10407==    by 0x400E73B: _dl_allocate_tls (dl-tls.c:467)
==10407==    by 0x4031A93: pthread_create@@GLIBC_2.1 (allocatestack.c:515)
==10407==    by 0x8048CA4: main (main.cpp:21)
==10407==
==10407== Invalid write of size 1
==10407==    at 0x4030FFA: __pthread_init_static_tls (allocatestack.c:942)
==10407==    by 0x400F9AC: dl_open_worker (dl-open.c:452)
==10407==    by 0x400C0E3: _dl_catch_error (dl-error.c:178)
==10407==    by 0x400FB9B: _dl_open (dl-open.c:549)
==10407==    by 0x4027CFB: dlopen_doit (dlopen.c:66)
==10407==    by 0x400C0E3: _dl_catch_error (dl-error.c:178)
==10407==    by 0x4028260: _dlerror_run (dlerror.c:164)
==10407==    by 0x4027D7C: dlopen@@GLIBC_2.1 (dlopen.c:87)
==10407==    by 0x8048E1A: main (main.cpp:43)
==10407==  Address 0x4b710bc is 4 bytes after a block of size 144 alloc'd
==10407==    at 0x401FC3E: calloc (vg_replace_malloc.c:397)
==10407==    by 0x400E49B: allocate_dtv (dl-tls.c:304)
==10407==    by 0x400E73B: _dl_allocate_tls (dl-tls.c:467)
==10407==    by 0x4031A93: pthread_create@@GLIBC_2.1 (allocatestack.c:515)
==10407==    by 0x8048CA4: main (main.cpp:21)
==10407==
==10407== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 47 from 1)
==10407== malloc/free: in use at exit: 12,896 bytes in 78 blocks.
==10407== malloc/free: 78 allocs, 0 frees, 12,896 bytes allocated.
==10407== For counts of detected errors, rerun with: -v
==10407== searching for pointers to 78 not-freed blocks.
==10407== checked 10,646,920 bytes.
Comment 1 Tom Aernoudt 2009-04-14 16:37:30 UTC
Created attachment 3883 [details]
testcase to reproduce the problem
Comment 2 Tom Aernoudt 2009-04-15 09:23:01 UTC
glibc-2.8 and glibc-2.9 have the same problem
Comment 3 Tom Aernoudt 2009-04-16 08:54:34 UTC
The memory corruption is caused because gcc uses the static model for code
compiled without -fPIC.

Isn't it possible to prevent that shared libraries that use a static tls model
are loaded?
Comment 4 Ulrich Drepper 2009-04-19 21:46:05 UTC
I've checked in a patch which prevents modules with static TLS from being loaded
if we cannot guarantee that we have room in the DTVs.