ce426f
commit 62058ce612ed3459501b4c4332e268edfe977f59
ce426f
Author: Carlos O'Donell <carlos@redhat.com>
ce426f
Date:   Mon Sep 29 13:14:21 2014 -0400
ce426f
ce426f
    Correctly size profiling reloc table (bug 17411)
ce426f
    
ce426f
    During auditing or profiling modes the dynamic loader
ce426f
    builds a cache of the relocated PLT entries in order
ce426f
    to reuse them when called again through the same PLT
ce426f
    entry. This way the PLT entry is never completed and
ce426f
    the call into the resolver always results in profiling
ce426f
    or auditing code running.
ce426f
    
ce426f
    The problem is that the PLT relocation cache size
ce426f
    is not computed correctly. The size of the cache
ce426f
    should be "Size of a relocation result structure"
ce426f
    x "Number of PLT-related relocations". Instead the
ce426f
    code erroneously computes "Size of a relocation
ce426f
    result" x "Number of bytes worth of PLT-related
ce426f
    relocations". I can only assume this was a mistake
ce426f
    in the understanding of the value of DT_PLTRELSZ
ce426f
    which is the number of bytes of PLT-related relocs.
ce426f
    We do have a DT_RELACOUNT entry, which is a count
ce426f
    for dynamic relative relocs, but we have no
ce426f
    DT_PLTRELCOUNT and thus we need to compute it.
ce426f
    
ce426f
    This patch corrects the computation of the size of the
ce426f
    relocation table used by the glibc profiling code.
ce426f
    
ce426f
    For more details see:
ce426f
    https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html
ce426f
    
ce426f
    	[BZ #17411]
ce426f
    	* elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for
ce426f
    	l_reloc_result.
ce426f
ce426f
diff --git glibc-2.17-c758a686/elf/dl-reloc.c glibc-2.17-c758a686/elf/dl-reloc.c
ce426f
index d2c6dac..97a7119 100644
ce426f
--- glibc-2.17-c758a686/elf/dl-reloc.c
ce426f
+++ glibc-2.17-c758a686/elf/dl-reloc.c
ce426f
@@ -279,8 +279,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
ce426f
 			      l->l_name);
ce426f
 	  }
ce426f
 
ce426f
-	l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]),
ce426f
-				    l->l_info[DT_PLTRELSZ]->d_un.d_val);
ce426f
+	size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA
ce426f
+			   ? sizeof (ElfW(Rela))
ce426f
+			   : sizeof (ElfW(Rel));
ce426f
+	size_t relcount = l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeofrel;
ce426f
+	l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), relcount);
ce426f
+
ce426f
 	if (l->l_reloc_result == NULL)
ce426f
 	  {
ce426f
 	    errstring = N_("\