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