This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: patch for ld-2.2.5.so segv



Geoff Keating wrote:

Date: Thu, 27 Jun 2002 11:29:41 -0700
From: Raymond Lo <lo@broadon.com>


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.

Yes, I see the problem.

I think, though, that a better fix might be to just change the
expression in elf_dynamic_do_rel to:

r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));

Does this work for you?

Sure it does.   This fix is better in the sense that it saves several stores instructions.  The downside is that r is still used before defined, although the behavior of program does not depend on the random value of r.  This might not be obvious to people new to this code.   Some comments would help.

-Raymond



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







Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]