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


> 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>


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