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