patch for ld-2.2.5.so segv
Raymond Lo
lo@broadon.com
Sat Jun 29 10:01:00 GMT 2002
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]) \
>> { \
>>
>>
>>
>
>
More information about the Libc-alpha
mailing list