patch for ld-2.2.5.so segv

Raymond Lo lo@broadon.com
Thu Jun 27 14:12:00 GMT 2002


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])                          \
       {                                          \





More information about the Libc-alpha mailing list