This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
patch for ld-2.2.5.so segv
- From: Raymond Lo <lo at broadon dot com>
- To: libc-alpha at sources dot redhat dot com
- Date: Thu, 27 Jun 2002 11:29:41 -0700
- Subject: patch for ld-2.2.5.so segv
- Organization: BroadOn Communications
This is a patch for a segv in the dynamic linker in glibc-2.2.5. The
problem shows up on a powerpc platform with glibc-2.2.5 compiled with
gcc-3.1 compiler, but I think this is a generic problem for other
platform. The application needs to do consecutive dlopen with
RTLD_NOW to trigger this bug. e.g.,
dlopen(dso, RTLD_NOW | RTLD_GLOBAL);
dlopen(dso1, RTLD_NOW | RTLD_GLOBAL);
The problem is caused by uninitialized array ranges[] in
glibc-2.2.5/elf/dynamic-link.h. In my test case, ranges[2].start has
0xffffffff
and the size of the reloc table is 0. When executing
elf_dynamic_do_rel in do-rel.h, r is updated and wraps around.
# r is 0xffffffff
# end is 0xffffffff
# nrelative is 0x83
r = MIN (r + nrelative, end);
Later, accessing r->r_info causes a segv. The condition r < end is true
because r = r + nrelative.
for (; r < end; ++r)
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-Raymond
email: lo@broadon.com
==================
diff -u -r1.1.1.1 dynamic-link.h
--- dynamic-link.h 2001/07/06 04:54:46 1.1.1.1
+++ dynamic-link.h 2002/06/27 18:16:55
@@ -142,6 +142,7 @@
ranges[0].lazy = ranges[2].lazy = 0; \
ranges[1].lazy = 1; \
ranges[0].size = ranges[1].size = ranges[2].size = 0; \
+ ranges[0].start = ranges[1].start = ranges[2].start = 0; \
\
if ((map)->l_info[DT_##RELOC]) \
{ \
@@ -173,7 +174,7 @@
int ranges_index; \
ranges[0].lazy = 0; \
ranges[0].size = ranges[1].size = 0; \
- ranges[0].start = 0; \
+ ranges[0].start = ranges[1].start = 0;
\
if ((map)->l_info[DT_##RELOC]) \
{ \