This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: patch for ld-2.2.5.so segv
- From: Geoff Keating <geoffk at geoffk dot org>
- To: lo at broadon dot com
- Cc: libc-alpha at sources dot redhat dot com
- Date: Fri, 28 Jun 2002 07:34:56 -0700
- Subject: Re: patch for ld-2.2.5.so segv
- References: <3D1B5995.4080306@broadon.com>
- Reply-to: Geoff Keating <geoffk at redhat dot com>
> 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?
> 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]) \
> { \
>
>
>
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>