Mark J. Wielaard 22346c
--- elfutils/libdwfl/ChangeLog
Mark J. Wielaard 22346c
+++ elfutils/libdwfl/ChangeLog
Mark Wielaard d10bca
@@ -48,6 +48,11 @@
Mark J. Wielaard 22346c
 	* dwfl_module_getdwarf.c (open_elf): Clear errno before CBFAIL.
Mark J. Wielaard 22346c
 	Reported by Kurt Roeckx <kurt@roeckx.be>.
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
+2011-03-23  Petr Machata  <pmachata@redhat.com>
Mark J. Wielaard 22346c
+
Mark J. Wielaard 22346c
+	* relocate.c (relocate_section): Use gelf_fsize instead of relying
Mark J. Wielaard 22346c
+	on shdr->sh_entsize.
Mark J. Wielaard 22346c
+
Mark J. Wielaard 22346c
 2011-02-11  Roland McGrath  <roland@redhat.com>
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
 	* linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz
Mark J. Wielaard 22346c
--- elfutils/libdwfl/relocate.c
Mark J. Wielaard 22346c
+++ elfutils/libdwfl/relocate.c
Mark J. Wielaard 22346c
@@ -1,5 +1,5 @@
Mark J. Wielaard 22346c
 /* Relocate debug information.
Mark J. Wielaard 22346c
-   Copyright (C) 2005-2010 Red Hat, Inc.
Mark J. Wielaard 22346c
+   Copyright (C) 2005-2011 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
Mark J. Wielaard 22346c
 
Mark Wielaard d10bca
    This file is free software; you can redistribute it and/or modify
Mark Wielaard d10bca
@@ -457,7 +457,10 @@ relocate_section (Dwfl_Module *mod, Elf
Mark J. Wielaard 22346c
       }
Mark J. Wielaard 22346c
   }
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
-  size_t nrels = shdr->sh_size / shdr->sh_entsize;
Mark J. Wielaard 22346c
+  size_t sh_entsize
Mark J. Wielaard 22346c
+    = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
Mark J. Wielaard 22346c
+		  1, EV_CURRENT);
Mark J. Wielaard 22346c
+  size_t nrels = shdr->sh_size / sh_entsize;
Mark J. Wielaard 22346c
   size_t complete = 0;
Mark J. Wielaard 22346c
   if (shdr->sh_type == SHT_REL)
Mark J. Wielaard 22346c
     for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
Mark Wielaard d10bca
@@ -559,7 +562,7 @@ relocate_section (Dwfl_Module *mod, Elf
Mark J. Wielaard 22346c
 	  nrels = next;
Mark J. Wielaard 22346c
 	}
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
-      shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
Mark J. Wielaard 22346c
+      shdr->sh_size = reldata->d_size = nrels * sh_entsize;
Mark J. Wielaard 22346c
       gelf_update_shdr (scn, shdr);
Mark J. Wielaard 22346c
     }
Mark J. Wielaard 22346c
 
roland 5c16b0
--- elfutils/libelf/ChangeLog
roland 5c16b0
+++ elfutils/libelf/ChangeLog
Mark Wielaard d10bca
@@ -676,10 +676,53 @@
roland 5c16b0
 	If section content hasn't been read yet, do it before looking for the
roland 5c16b0
 	block size.  If no section data present, infer size of section header.
roland 5c16b0
 
roland 5c16b0
+2005-05-14  Jakub Jelinek  <jakub@redhat.com>
roland 5c16b0
+
roland 5c16b0
+	* libelfP.h (INVALID_NDX): Define.
roland 5c16b0
+	* gelf_getdyn.c (gelf_getdyn): Use it.  Remove ndx < 0 test if any.
roland 5c16b0
+	* gelf_getlib.c (gelf_getlib): Likewise.
roland 5c16b0
+	* gelf_getmove.c (gelf_getmove): Likewise.
roland 5c16b0
+	* gelf_getrel.c (gelf_getrel): Likewise.
roland 5c16b0
+	* gelf_getrela.c (gelf_getrela): Likewise.
roland 5c16b0
+	* gelf_getsym.c (gelf_getsym): Likewise.
roland 5c16b0
+	* gelf_getsyminfo.c (gelf_getsyminfo): Likewise.
roland 5c16b0
+	* gelf_getsymshndx.c (gelf_getsymshndx): Likewise.
roland 5c16b0
+	* gelf_getversym.c (gelf_getversym): Likewise.
roland 5c16b0
+	* gelf_update_dyn.c (gelf_update_dyn): Likewise.
roland 5c16b0
+	* gelf_update_lib.c (gelf_update_lib): Likewise.
roland 5c16b0
+	* gelf_update_move.c (gelf_update_move): Likewise.
roland 5c16b0
+	* gelf_update_rel.c (gelf_update_rel): Likewise.
roland 5c16b0
+	* gelf_update_rela.c (gelf_update_rela): Likewise.
roland 5c16b0
+	* gelf_update_sym.c (gelf_update_sym): Likewise.
roland 5c16b0
+	* gelf_update_syminfo.c (gelf_update_syminfo): Likewise.
roland 5c16b0
+	* gelf_update_symshndx.c (gelf_update_symshndx): Likewise.
roland 5c16b0
+	* gelf_update_versym.c (gelf_update_versym): Likewise.
roland 5c16b0
+	* elf_newscn.c (elf_newscn): Check for overflow.
roland 5c16b0
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise.
roland 5c16b0
+	(__elfw2(LIBELFBITS,updatefile)): Likewise.
roland 5c16b0
+	* elf_begin.c (file_read_elf): Likewise.
roland 5c16b0
+	* elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise.
roland 5c16b0
+	* elf_getarsym.c (elf_getarsym): Likewise.
roland 5c16b0
+	* elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)): Likewise.
roland 5c16b0
 2005-05-11  Ulrich Drepper  <drepper@redhat.com>
roland 5c16b0
 
roland 5c16b0
 	* elf.h: Update again.
roland f790d2
 
roland f790d2
+2005-05-17  Jakub Jelinek  <jakub@redhat.com>
roland f790d2
+
roland f790d2
+	* elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header
roland f790d2
+	table fits into object's bounds.
roland f790d2
+	* elf_getshstrndx.c (elf_getshstrndx): Add elf->start_offset to
roland f790d2
+	elf->map_address.  Check if first section header fits into object's
roland f790d2
+	bounds.
roland f790d2
+	* elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)):
roland f790d2
+	Check if section header table fits into object's bounds.
roland f790d2
+	* elf_begin.c (get_shnum): Ensure section headers fits into
roland f790d2
+	object's bounds.
roland f790d2
+	(file_read_elf): Make sure scncnt is small enough to allocate both
roland f790d2
+	ElfXX_Shdr and Elf_Scn array.  Make sure section and program header
roland f790d2
+	tables fit into object's bounds.  Avoid memory leak on failure.
roland f790d2
+
roland f790d2
 2005-05-09  Ulrich Drepper  <drepper@redhat.com>
roland f790d2
 
roland f790d2
 	* elf.h: Update from glibc.
roland 5c16b0
--- elfutils/libelf/elf32_getphdr.c
roland 5c16b0
+++ elfutils/libelf/elf32_getphdr.c
Mark Wielaard d10bca
@@ -93,6 +93,16 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf)
roland 840723
 
roland 44874c
       if (elf->map_address != NULL)
roland 44874c
 	{
roland 44874c
+	  /* First see whether the information in the ELF header is
roland 44874c
+	     valid and it does not ask for too much.  */
roland 44874c
+	  if (unlikely (ehdr->e_phoff >= elf->maximum_size)
roland e4d1f5
+	      || unlikely (elf->maximum_size - ehdr->e_phoff < size))
roland 44874c
+	    {
roland 44874c
+	      /* Something is wrong.  */
roland 44874c
+	      __libelf_seterrno (ELF_E_INVALID_PHDR);
roland 44874c
+	      goto out;
roland 44874c
+	    }
roland 840723
+
roland 44874c
 	  /* All the data is already mapped.  Use it.  */
roland 44874c
 	  void *file_phdr = ((char *) elf->map_address
roland 44874c
 			     + elf->start_offset + ehdr->e_phoff);
roland 5c16b0
--- elfutils/libelf/elf32_getshdr.c
roland 5c16b0
+++ elfutils/libelf/elf32_getshdr.c
roland 44874c
@@ -1,5 +1,5 @@
roland 44874c
 /* Return section header.
roland d36848
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2009 Red Hat, Inc.
roland d36848
+   Copyright (C) 1998-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland 44874c
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
roland 44874c
 
Mark Wielaard d10bca
@@ -60,7 +60,8 @@ load_shdr_wrlock (Elf_Scn *scn)
roland 44874c
     goto out;
roland 44874c
 
roland 44874c
   size_t shnum;
roland d36848
-  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0)
roland d36848
+  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
roland 44874c
+      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
roland 44874c
     goto out;
roland 44874c
   size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
roland 44874c
 
Mark Wielaard d10bca
@@ -77,6 +78,16 @@ load_shdr_wrlock (Elf_Scn *scn)
roland 44874c
 
roland 44874c
   if (elf->map_address != NULL)
roland 44874c
     {
roland 44874c
+      /* First see whether the information in the ELF header is
roland 44874c
+	 valid and it does not ask for too much.  */
roland 44874c
+      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
roland e4d1f5
+	  || unlikely (elf->maximum_size - ehdr->e_shoff < size))
roland 44874c
+	{
roland 44874c
+	  /* Something is wrong.  */
roland 44874c
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
roland 44874c
+	  goto free_and_out;
roland 44874c
+	}
roland 840723
+
roland 44874c
       ElfW2(LIBELFBITS,Shdr) *notcvt;
roland 840723
 
roland 44874c
       /* All the data is already mapped.  If we could use it
roland 5c16b0
--- elfutils/libelf/elf32_newphdr.c
roland 5c16b0
+++ elfutils/libelf/elf32_newphdr.c
Mark Wielaard d10bca
@@ -114,6 +114,12 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
roland 8cafad
 	   || count == PN_XNUM
roland 44874c
 	   || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
roland 44874c
     {
roland 44874c
+      if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
roland 44874c
+	{
roland 44874c
+	  result = NULL;
roland 44874c
+	  goto out;
roland 44874c
+	}
roland 44874c
+
roland 44874c
       /* Allocate a new program header with the appropriate number of
roland 44874c
 	 elements.  */
roland 44874c
       result = (ElfW2(LIBELFBITS,Phdr) *)
roland 5c16b0
--- elfutils/libelf/elf32_updatefile.c
roland 5c16b0
+++ elfutils/libelf/elf32_updatefile.c
Mark Wielaard d10bca
@@ -202,6 +202,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf
roland 44874c
   /* Write all the sections.  Well, only those which are modified.  */
roland 44874c
   if (shnum > 0)
roland 44874c
     {
roland 44874c
+      if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
roland 44874c
+ 	return 1;
roland 44874c
+
roland 44874c
       Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
roland 44874c
       Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
roland 44874c
       char *const shdr_start = ((char *) elf->map_address + elf->start_offset
Mark Wielaard d10bca
@@ -624,6 +627,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf
roland 44874c
   /* Write all the sections.  Well, only those which are modified.  */
roland 44874c
   if (shnum > 0)
roland 44874c
     {
roland 44874c
+      if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
roland 44874c
+					+ sizeof (ElfW2(LIBELFBITS,Shdr)))))
roland 44874c
+	return 1;
roland 44874c
+
roland 44874c
       off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
roland 44874c
 #if EV_NUM != 2
roland 44874c
       xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
roland 5c16b0
--- elfutils/libelf/elf_begin.c
roland 5c16b0
+++ elfutils/libelf/elf_begin.c
Mark Wielaard d10bca
@@ -144,7 +144,8 @@ get_shnum (void *map_address, unsigned c
roland 840723
 
roland 44874c
       if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
roland 44874c
 	{
roland 44874c
-	  if (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
roland 44874c
+	  if (unlikely (ehdr.e32->e_shoff >= maxsize)
roland e4d1f5
+	      || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
roland 44874c
 	    /* Cannot read the first section header.  */
roland 44874c
 	    return 0;
roland 840723
 
Mark Wielaard d10bca
@@ -192,7 +193,8 @@ get_shnum (void *map_address, unsigned c
roland 840723
 
roland 44874c
       if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
roland 840723
 	{
roland 44874c
-	  if (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
roland 44874c
+	  if (unlikely (ehdr.e64->e_shoff >= maxsize)
roland 44874c
+	      || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
roland 44874c
 	    /* Cannot read the first section header.  */
roland 44874c
 	    return 0;
roland 840723
 
Mark Wielaard d10bca
@@ -264,6 +266,15 @@ file_read_elf (int fildes, void *map_add
roland 44874c
     /* Could not determine the number of sections.  */
roland 44874c
     return NULL;
roland 840723
 
roland 44874c
+  /* Check for too many sections.  */
roland 44874c
+  if (e_ident[EI_CLASS] == ELFCLASS32)
roland 44874c
+    {
roland 44874c
+      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
roland 44874c
+	return NULL;
roland 44874c
+    }
roland 44874c
+  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
roland 44874c
+    return NULL;
roland 840723
+
roland 8cafad
   /* We can now allocate the memory.  Even if there are no section headers,
roland 8cafad
      we allocate space for a zeroth section in case we need it later.  */
roland 8cafad
   const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
Mark Wielaard d10bca
@@ -303,6 +314,16 @@ file_read_elf (int fildes, void *map_add
roland 840723
 	{
roland 44874c
 	  /* We can use the mmapped memory.  */
roland 44874c
 	  elf->state.elf32.ehdr = ehdr;
roland 840723
+
roland 44874c
+	  if (unlikely (ehdr->e_shoff >= maxsize)
roland e4d1f5
+	      || unlikely (maxsize - ehdr->e_shoff
roland e4d1f5
+			   < scncnt * sizeof (Elf32_Shdr)))
roland 44874c
+	    {
roland 44874c
+	    free_and_out:
roland 44874c
+	      free (elf);
roland 44874c
+	      __libelf_seterrno (ELF_E_INVALID_FILE);
roland 44874c
+	      return NULL;
roland 44874c
+	    }
roland 44874c
 	  elf->state.elf32.shdr
roland 44874c
 	    = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
roland 840723
 
Mark Wielaard d10bca
@@ -389,6 +410,11 @@ file_read_elf (int fildes, void *map_add
roland 44874c
 	{
roland 44874c
 	  /* We can use the mmapped memory.  */
roland 44874c
 	  elf->state.elf64.ehdr = ehdr;
roland 44874c
+
roland 44874c
+	  if (unlikely (ehdr->e_shoff >= maxsize)
roland 44874c
+	      || unlikely (ehdr->e_shoff
roland 44874c
+			   + scncnt * sizeof (Elf32_Shdr) > maxsize))
roland 44874c
+	    goto free_and_out;
roland 44874c
 	  elf->state.elf64.shdr
roland 44874c
 	    = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
roland 840723
 
roland 5c16b0
--- elfutils/libelf/elf_getarsym.c
roland 5c16b0
+++ elfutils/libelf/elf_getarsym.c
Mark Wielaard d10bca
@@ -158,6 +158,9 @@ elf_getarsym (elf, ptr)
roland 44874c
       size_t index_size = atol (tmpbuf);
roland 840723
 
roland 44874c
       if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
roland 44874c
+#if SIZE_MAX <= 4294967295U
roland 44874c
+	  || n >= SIZE_MAX / sizeof (Elf_Arsym)
roland 44874c
+#endif
roland 44874c
 	  || n * sizeof (uint32_t) > index_size)
roland 44874c
 	{
roland 44874c
 	  /* This index table cannot be right since it does not fit into
roland d36848
--- elfutils/libelf/elf_getshdrstrndx.c
roland d36848
+++ elfutils/libelf/elf_getshdrstrndx.c
Mark Wielaard d10bca
@@ -104,10 +104,25 @@ elf_getshdrstrndx (elf, dst)
roland 44874c
 	      if (elf->map_address != NULL
roland 44874c
 		  && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
roland 44874c
 		  && (ALLOW_UNALIGNED
roland 44874c
-		      || (((size_t) ((char *) elf->map_address + offset))
roland 44874c
+		      || (((size_t) ((char *) elf->map_address
roland 44874c
+			   + elf->start_offset + offset))
roland 44874c
 			  & (__alignof__ (Elf32_Shdr) - 1)) == 0))
roland e4d1f5
-		/* We can directly access the memory.  */
roland e4d1f5
-		num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
roland 44874c
+		{
roland 44874c
+		  /* First see whether the information in the ELF header is
roland 44874c
+		     valid and it does not ask for too much.  */
roland e4d1f5
+		  if (unlikely (elf->maximum_size - offset
roland e4d1f5
+				< sizeof (Elf32_Shdr)))
roland 44874c
+		    {
roland 44874c
+		      /* Something is wrong.  */
roland 44874c
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
roland 44874c
+		      result = -1;
roland 44874c
+		      goto out;
roland 44874c
+		    }
roland 44874c
+
roland e4d1f5
+		  /* We can directly access the memory.  */
roland 44874c
+		  num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
roland 44874c
+					 + offset))->sh_link;
roland 44874c
+		}
roland 44874c
 	      else
roland 44874c
 		{
roland 44874c
 		  /* We avoid reading in all the section headers.  Just read
Mark Wielaard d10bca
@@ -142,10 +157,25 @@ elf_getshdrstrndx (elf, dst)
roland 44874c
 	      if (elf->map_address != NULL
roland 44874c
 		  && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
roland 44874c
 		  && (ALLOW_UNALIGNED
roland 44874c
-		      || (((size_t) ((char *) elf->map_address + offset))
roland 44874c
+		      || (((size_t) ((char *) elf->map_address
roland 44874c
+			   + elf->start_offset + offset))
roland 44874c
 			  & (__alignof__ (Elf64_Shdr) - 1)) == 0))
roland e4d1f5
-		/* We can directly access the memory.  */
roland e4d1f5
-		num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
roland 44874c
+		{
roland 44874c
+		  /* First see whether the information in the ELF header is
roland 44874c
+		     valid and it does not ask for too much.  */
roland e4d1f5
+		  if (unlikely (elf->maximum_size - offset
roland e4d1f5
+				< sizeof (Elf64_Shdr)))
roland 44874c
+		    {
roland 44874c
+		      /* Something is wrong.  */
roland 44874c
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
roland 44874c
+		      result = -1;
roland 44874c
+		      goto out;
roland 44874c
+		    }
roland 44874c
+
roland e4d1f5
+		  /* We can directly access the memory.  */
roland e4d1f5
+		  num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
roland e4d1f5
+					 + offset))->sh_link;
roland 44874c
+		}
roland 44874c
 	      else
roland 44874c
 		{
roland 44874c
 		  /* We avoid reading in all the section headers.  Just read
roland 5c16b0
--- elfutils/libelf/elf_newscn.c
roland 5c16b0
+++ elfutils/libelf/elf_newscn.c
Mark Wielaard d10bca
@@ -83,10 +83,18 @@ elf_newscn (elf)
roland 44874c
   else
roland 840723
     {
roland 44874c
       /* We must allocate a new element.  */
roland 44874c
-      Elf_ScnList *newp;
roland 44874c
+      Elf_ScnList *newp = NULL;
roland 840723
 
roland 44874c
       assert (elf->state.elf.scnincr > 0);
roland 840723
 
roland 44874c
+      if (
roland 44874c
+#if SIZE_MAX <= 4294967295U
roland 44874c
+	  likely (elf->state.elf.scnincr
roland 44874c
+		  < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
roland 44874c
+#else
roland 44874c
+	  1
roland 44874c
+#endif
roland 44874c
+	  )
roland 44874c
       newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
roland 44874c
 				     + ((elf->state.elf.scnincr *= 2)
roland 44874c
 					* sizeof (Elf_Scn)), 1);
roland 5c16b0
--- elfutils/libelf/gelf_getdyn.c
roland 5c16b0
+++ elfutils/libelf/gelf_getdyn.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get information from dynamic table at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -72,7 +72,7 @@ gelf_getdyn (data, ndx, dst)
roland 44874c
 	 table entries has to be adopted.  The user better has provided
roland 44874c
 	 a buffer where we can store the information.  While copying the
roland 44874c
 	 data we are converting the format.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -93,7 +93,7 @@ gelf_getdyn (data, ndx, dst)
roland 840723
 
roland 44874c
       /* The data is already in the correct form.  Just make sure the
roland 44874c
 	 index is OK.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, GElf_Dyn, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_getlib.c
roland 5c16b0
+++ elfutils/libelf/gelf_getlib.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get library from table at the given index.
roland e4d1f5
-   Copyright (C) 2004 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2004-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -65,7 +65,7 @@ gelf_getlib (data, ndx, dst)
roland 44874c
   /* The data is already in the correct form.  Just make sure the
roland 44874c
      index is OK.  */
roland 44874c
   GElf_Lib *result = NULL;
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Lib, data))
roland 44874c
     __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
   else
roland 840723
     {
roland 5c16b0
--- elfutils/libelf/gelf_getmove.c
roland 5c16b0
+++ elfutils/libelf/gelf_getmove.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get move structure at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -62,7 +62,7 @@ gelf_getmove (data, ndx, dst)
roland 840723
 
roland 44874c
   /* The data is already in the correct form.  Just make sure the
roland 44874c
      index is OK.  */
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Move, data))
roland 840723
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
       goto out;
roland 5c16b0
--- elfutils/libelf/gelf_getrela.c
roland 5c16b0
+++ elfutils/libelf/gelf_getrela.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get RELA relocation information at given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -50,12 +50,6 @@ gelf_getrela (data, ndx, dst)
roland 44874c
   if (data_scn == NULL)
roland 44874c
     return NULL;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return NULL;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_RELA))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_HANDLE);
Mark Wielaard d10bca
@@ -72,7 +66,7 @@ gelf_getrela (data, ndx, dst)
roland 44874c
   if (scn->elf->class == ELFCLASS32)
roland 44874c
     {
roland 44874c
       /* We have to convert the data.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  result = NULL;
Mark Wielaard d10bca
@@ -93,7 +87,7 @@ gelf_getrela (data, ndx, dst)
roland 44874c
     {
roland 44874c
       /* Simply copy the data after we made sure we are actually getting
roland 44874c
 	 correct data.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  result = NULL;
roland 5c16b0
--- elfutils/libelf/gelf_getrel.c
roland 5c16b0
+++ elfutils/libelf/gelf_getrel.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get REL relocation information at given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -50,12 +50,6 @@ gelf_getrel (data, ndx, dst)
roland 44874c
   if (data_scn == NULL)
roland 44874c
     return NULL;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return NULL;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_REL))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_HANDLE);
Mark Wielaard d10bca
@@ -72,7 +66,7 @@ gelf_getrel (data, ndx, dst)
roland 44874c
   if (scn->elf->class == ELFCLASS32)
roland 44874c
     {
roland 44874c
       /* We have to convert the data.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  result = NULL;
Mark Wielaard d10bca
@@ -92,7 +86,7 @@ gelf_getrel (data, ndx, dst)
roland 44874c
     {
roland 44874c
       /* Simply copy the data after we made sure we are actually getting
roland 44874c
 	 correct data.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  result = NULL;
roland 5c16b0
--- elfutils/libelf/gelf_getsym.c
roland 5c16b0
+++ elfutils/libelf/gelf_getsym.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get symbol information from symbol table at the given index.
roland e4d1f5
-   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 1999-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -69,7 +69,7 @@ gelf_getsym (data, ndx, dst)
roland 44874c
 	 table entries has to be adopted.  The user better has provided
roland 44874c
 	 a buffer where we can store the information.  While copying the
roland 44874c
 	 data we are converting the format.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Sym, data))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -98,7 +98,7 @@ gelf_getsym (data, ndx, dst)
roland 6b412c
 
roland 44874c
       /* The data is already in the correct form.  Just make sure the
roland 44874c
 	 index is OK.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, GElf_Sym, data))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_getsyminfo.c
roland 5c16b0
+++ elfutils/libelf/gelf_getsyminfo.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get additional symbol information from symbol table at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -63,7 +63,7 @@ gelf_getsyminfo (data, ndx, dst)
roland bf5b25
 
roland 44874c
   /* The data is already in the correct form.  Just make sure the
roland 44874c
      index is OK.  */
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Syminfo, data))
roland bf5b25
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
       goto out;
roland 5c16b0
--- elfutils/libelf/gelf_getsymshndx.c
roland 5c16b0
+++ elfutils/libelf/gelf_getsymshndx.c
roland e4d1f5
@@ -1,6 +1,6 @@
roland e4d1f5
 /* Get symbol information and separate section index from symbol table
roland e4d1f5
    at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -69,7 +69,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
roland 44874c
      section index table.  */
roland 44874c
   if (likely (shndxdata_scn != NULL))
roland 44874c
     {
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -89,7 +89,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
roland 44874c
 	 table entries has to be adopted.  The user better has provided
roland 44874c
 	 a buffer where we can store the information.  While copying the
roland 44874c
 	 data we are converting the format.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Sym, symdata))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -118,7 +118,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
roland bf5b25
 
roland 44874c
       /* The data is already in the correct form.  Just make sure the
roland 44874c
 	 index is OK.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, GElf_Sym, symdata))
roland bf5b25
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_getversym.c
roland 5c16b0
+++ elfutils/libelf/gelf_getversym.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Get symbol version information at the given index.
roland e4d1f5
-   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 1999-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -71,7 +71,7 @@ gelf_getversym (data, ndx, dst)
roland bf5b25
 
roland 44874c
   /* The data is already in the correct form.  Just make sure the
roland 44874c
      index is OK.  */
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Versym, data))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
       result = NULL;
roland 5c16b0
--- elfutils/libelf/gelf_update_dyn.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_dyn.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update information in dynamic table at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -50,12 +50,6 @@ gelf_update_dyn (data, ndx, src)
roland 44874c
   if (data == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_DYN))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -81,7 +75,7 @@ gelf_update_dyn (data, ndx, src)
roland 6b412c
 	}
roland bf5b25
 
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
roland bf5b25
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -95,7 +89,7 @@ gelf_update_dyn (data, ndx, src)
roland 44874c
   else
roland 44874c
     {
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Dyn, &data_scn->d))
roland bf5b25
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_lib.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_lib.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update library in table at the given index.
roland e4d1f5
-   Copyright (C) 2004 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2004-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -47,12 +47,6 @@ gelf_update_lib (data, ndx, src)
roland 44874c
   if (data == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_LIB))
roland 44874c
     {
Mark Wielaard d10bca
@@ -66,7 +60,7 @@ gelf_update_lib (data, ndx, src)
roland bf5b25
 
roland 44874c
   /* Check whether we have to resize the data buffer.  */
roland 44874c
   int result = 0;
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, Elf64_Lib, &data_scn->d))
roland 44874c
     __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
   else
roland 44874c
     {
roland 5c16b0
--- elfutils/libelf/gelf_update_move.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_move.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update move structure at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -54,8 +54,7 @@ gelf_update_move (data, ndx, src)
roland 44874c
   assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
roland bf5b25
 
roland 44874c
   /* Check whether we have to resize the data buffer.  */
roland 44874c
-  if (unlikely (ndx < 0)
roland e4d1f5
-      || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Move, &data_scn->d))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland e4d1f5
       return 0;
roland 5c16b0
--- elfutils/libelf/gelf_update_rela.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_rela.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update RELA relocation information at given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -47,12 +47,6 @@ gelf_update_rela (Elf_Data *dst, int ndx
roland 44874c
   if (dst == NULL)
roland 44874c
     return 0;
roland 44874c
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_RELA))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -80,7 +74,7 @@ gelf_update_rela (Elf_Data *dst, int ndx
roland 44874c
 	}
roland 44874c
 
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -96,7 +90,7 @@ gelf_update_rela (Elf_Data *dst, int ndx
roland 44874c
   else
roland 44874c
     {
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_rel.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_rel.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update REL relocation information at given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -47,12 +47,6 @@ gelf_update_rel (Elf_Data *dst, int ndx,
roland 44874c
   if (dst == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_REL))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -78,7 +72,7 @@ gelf_update_rel (Elf_Data *dst, int ndx,
roland 44874c
 	}
roland bf5b25
 
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -93,7 +87,7 @@ gelf_update_rel (Elf_Data *dst, int ndx,
roland 44874c
   else
roland 44874c
     {
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_sym.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_sym.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update symbol information in symbol table at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -51,12 +51,6 @@ gelf_update_sym (data, ndx, src)
roland 44874c
   if (data == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_SYM))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -81,7 +75,7 @@ gelf_update_sym (data, ndx, src)
roland 44874c
 	}
roland bf5b25
 
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Sym, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -104,7 +98,7 @@ gelf_update_sym (data, ndx, src)
roland 44874c
   else
roland 44874c
     {
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Sym, &data_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_syminfo.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_syminfo.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update additional symbol information in symbol table at the given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -51,12 +51,6 @@ gelf_update_syminfo (data, ndx, src)
roland 44874c
   if (data == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -72,7 +66,7 @@ gelf_update_syminfo (data, ndx, src)
roland 44874c
   rwlock_wrlock (scn->elf->lock);
roland bf5b25
 
roland 44874c
   /* Check whether we have to resize the data buffer.  */
roland 44874c
-  if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Syminfo, &data_scn->d))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
       goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_symshndx.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_symshndx.c
roland e4d1f5
@@ -1,6 +1,6 @@
roland e4d1f5
 /* Update symbol information and section index in symbol table at the
roland e4d1f5
    given index.
roland e4d1f5
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2000-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -56,12 +56,6 @@ gelf_update_symshndx (symdata, shndxdata
roland 44874c
   if (symdata == NULL)
roland 44874c
     return 0;
roland bf5b25
 
roland 44874c
-  if (unlikely (ndx < 0))
roland 44874c
-    {
roland 44874c
-      __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
-      return 0;
roland 44874c
-    }
roland 44874c
-
roland 44874c
   if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
roland 44874c
     {
roland 44874c
       /* The type of the data better should match.  */
Mark Wielaard d10bca
@@ -107,7 +101,7 @@ gelf_update_symshndx (symdata, shndxdata
roland 44874c
 	}
roland bf5b25
 
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
Mark Wielaard d10bca
@@ -130,7 +124,7 @@ gelf_update_symshndx (symdata, shndxdata
roland 44874c
   else
roland 44874c
     {
roland 44874c
       /* Check whether we have to resize the data buffer.  */
roland 44874c
-      if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
roland e4d1f5
+      if (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d))
roland 44874c
 	{
roland 44874c
 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
roland 44874c
 	  goto out;
roland 5c16b0
--- elfutils/libelf/gelf_update_versym.c
roland 5c16b0
+++ elfutils/libelf/gelf_update_versym.c
roland e4d1f5
@@ -1,5 +1,5 @@
roland e4d1f5
 /* Update symbol version information.
roland e4d1f5
-   Copyright (C) 2001, 2002 Red Hat, Inc.
roland e4d1f5
+   Copyright (C) 2001-2009 Red Hat, Inc.
Mark Wielaard d10bca
    This file is part of elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
roland e4d1f5
 
Mark Wielaard d10bca
@@ -54,8 +54,7 @@ gelf_update_versym (data, ndx, src)
roland 44874c
   assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
roland bf5b25
 
roland 44874c
   /* Check whether we have to resize the data buffer.  */
roland 44874c
-  if (unlikely (ndx < 0)
roland e4d1f5
-      || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size))
roland e4d1f5
+  if (INVALID_NDX (ndx, GElf_Versym, &data_scn->d))
roland 44874c
     {
roland 44874c
       __libelf_seterrno (ELF_E_INVALID_INDEX);
roland e4d1f5
       return 0;
roland 5c16b0
--- elfutils/libelf/libelfP.h
roland 5c16b0
+++ elfutils/libelf/libelfP.h
Mark Wielaard d10bca
@@ -587,4 +587,8 @@ extern uint32_t __libelf_crc32 (uint32_t
roland 44874c
 /* Align offset to 4 bytes as needed for note name and descriptor data.  */
roland 44874c
 #define NOTE_ALIGN(n)	(((n) + 3) & -4U)
roland bf5b25
 
roland e4d1f5
+/* Convenience macro.  */
roland e4d1f5
+#define INVALID_NDX(ndx, type, data) \
roland e4d1f5
+  unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
roland 44874c
+
roland 44874c
 #endif  /* libelfP.h */
roland 5c16b0
--- elfutils/src/ChangeLog
roland 5c16b0
+++ elfutils/src/ChangeLog
Mark Wielaard d10bca
@@ -257,6 +257,12 @@
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
 	* readelf.c (dwarf_attr_string): Grok DW_AT_GNU_odr_signature.
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
+2011-03-23  Petr Machata  <pmachata@redhat.com>
Mark J. Wielaard 22346c
+
Mark J. Wielaard 22346c
+	* readelf.c (handle_dynamic, handle_relocs_rel)
Mark J. Wielaard 22346c
+	(handle_relocs_rela, handle_versym, print_liblist):
Mark J. Wielaard 22346c
+	Use gelf_fsize instead of relying on shdr->sh_entsize.
Mark J. Wielaard 22346c
+
Mark J. Wielaard 22346c
 2011-02-11  Roland McGrath  <roland@redhat.com>
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
 	* elfcmp.c (verbose): New variable.
Mark Wielaard d10bca
@@ -1969,6 +1975,16 @@
roland 5c16b0
 	object symbols or symbols with unknown type.
roland 5c16b0
 	(check_rel): Likewise.
roland 5c16b0
 
roland 5c16b0
+2005-06-09  Roland McGrath  <roland@redhat.com>
roland 5c16b0
+
roland 5c16b0
+	* readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link.
roland 5c16b0
+	(handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise.
roland 5c16b0
+	(handle_scngrp): Check for bogus sh_info.
roland 5c16b0
+
roland 5c16b0
+	* strip.c (handle_elf): Check for bogus values in sh_link, sh_info,
roland 5c16b0
+	st_shndx, e_shstrndx, and SHT_GROUP or SHT_SYMTAB_SHNDX data.
roland 5c16b0
+	Don't use assert on input values, instead bail with "illformed" error.
roland 5c16b0
+
roland 5c16b0
 2005-06-08  Roland McGrath  <roland@redhat.com>
roland 5c16b0
 
roland 5c16b0
 	* readelf.c (print_ops): Add consts.
Mark Wielaard d10bca
@@ -2014,6 +2030,19 @@
roland 5c16b0
 
roland 5c16b0
 	* readelf.c (dwarf_tag_string): Add new tags.
roland 5c16b0
 
roland 5c16b0
+2005-05-17  Jakub Jelinek  <jakub@redhat.com>
roland 5c16b0
+
roland 5c16b0
+	* elflint.c (check_hash): Don't check entries beyond end of section.
roland 5c16b0
+	(check_note): Don't crash if gelf_rawchunk fails.
roland 5c16b0
+	(section_name): Return <invalid> if gelf_getshdr returns NULL.
roland 5c16b0
+
roland 5c16b0
+2005-05-14  Jakub Jelinek  <jakub@redhat.com>
roland 5c16b0
+
roland 5c16b0
+	* elflint.c (section_name): Return "<invalid>" instead of
roland 5c16b0
+	crashing on invalid section name.
roland 5c16b0
+	(check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic,
roland 5c16b0
+	check_symtab_shndx, check_hash, check_versym): Robustify.
roland 5c16b0
+
roland 5c16b0
 2005-05-08  Roland McGrath  <roland@redhat.com>
roland 5c16b0
 
roland 5c16b0
 	* strip.c (handle_elf): Don't translate hash and versym data formats,
roland 5c16b0
--- elfutils/src/elflint.c
roland 5c16b0
+++ elfutils/src/elflint.c
Mark Wielaard d10bca
@@ -123,6 +123,10 @@ static uint32_t shstrndx;
roland 44874c
 /* Array to count references in section groups.  */
roland 44874c
 static int *scnref;
roland bf5b25
 
roland 8cafad
+/* Numbers of sections and program headers.  */
roland 44874c
+static unsigned int shnum;
roland 8cafad
+static unsigned int phnum;
roland 44874c
+
roland bf5b25
 
roland 44874c
 int
roland 44874c
 main (int argc, char *argv[])
Mark Wielaard d10bca
@@ -311,10 +315,19 @@ section_name (Ebl *ebl, int idx)
roland 44874c
 {
roland 44874c
   GElf_Shdr shdr_mem;
roland 44874c
   GElf_Shdr *shdr;
roland 44874c
+  const char *ret;
roland 44874c
+
roland 44874c
+  if ((unsigned int) idx > shnum)
roland 44874c
+    return "<invalid>";
roland bf5b25
 
roland 44874c
   shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
roland 44874c
+  if (shdr == NULL)
roland 44874c
+    return "<invalid>";
roland bf5b25
 
roland 44874c
-  return elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
roland 44874c
+  ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
roland 44874c
+  if (ret == NULL)
roland 44874c
+    return "<invalid>";
roland 44874c
+  return ret;
roland 44874c
 }
roland bf5b25
 
roland 54edc1
 
Mark Wielaard d10bca
@@ -336,11 +349,6 @@ static const int valid_e_machine[] =
roland 44874c
   (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
roland 54edc1
 
roland 54edc1
 
roland 8cafad
-/* Numbers of sections and program headers.  */
roland 44874c
-static unsigned int shnum;
roland 8cafad
-static unsigned int phnum;
roland 44874c
-
roland 44874c
-
roland 44874c
 static void
roland 44874c
 check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
roland 44874c
 {
Mark Wielaard d10bca
@@ -624,7 +632,8 @@ section [%2d] '%s': symbol table cannot
roland 44874c
 	  }
roland 44874c
       }
roland 54edc1
 
roland 44874c
-  if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
roland 44874c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
roland 44874c
+  if (shdr->sh_entsize != sh_entsize)
roland 44874c
     ERROR (gettext ("\
roland 44874c
 section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
roland 44874c
 	   idx, section_name (ebl, idx));
Mark Wielaard d10bca
@@ -662,7 +671,7 @@ section [%2d] '%s': XINDEX for zeroth en
roland 44874c
 	       xndxscnidx, section_name (ebl, xndxscnidx));
roland 44874c
     }
roland 54edc1
 
roland 44874c
-  for (size_t cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 44874c
+  for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt)
roland 44874c
     {
roland 44874c
       sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
roland 44874c
       if (sym == NULL)
Mark Wielaard d10bca
@@ -682,7 +691,8 @@ section [%2d] '%s': symbol %zu: invalid
roland 44874c
       else
roland bf5b25
 	{
roland 44874c
 	  name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
roland 44874c
-	  assert (name != NULL);
roland 44874c
+	  assert (name != NULL
roland 44874c
+		  || strshdr->sh_type != SHT_STRTAB);
roland 44874c
 	}
roland bf5b25
 
roland 44874c
       if (sym->st_shndx == SHN_XINDEX)
Mark Wielaard d10bca
@@ -1031,9 +1041,11 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
roland 44874c
     {
roland 44874c
       GElf_Shdr rcshdr_mem;
roland 44874c
       const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
roland 44874c
-      assert (rcshdr != NULL);
roland 44874c
 
roland 44874c
-      if (rcshdr->sh_type == SHT_DYNAMIC)
roland 44874c
+      if (rcshdr == NULL)
roland 44874c
+	break;
roland 44874c
+
roland 44874c
+      if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize)
roland bf5b25
 	{
roland 44874c
 	  /* Found the dynamic section.  Look through it.  */
roland 44874c
 	  Elf_Data *d = elf_getdata (scn, NULL);
Mark Wielaard d10bca
@@ -1043,7 +1055,9 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
roland 44874c
 	    {
roland 44874c
 	      GElf_Dyn dyn_mem;
roland 44874c
 	      GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
roland 44874c
-	      assert (dyn != NULL);
roland 44874c
+
roland 44874c
+	      if (dyn == NULL)
roland 44874c
+		break;
roland bf5b25
 
roland 44874c
 	      if (dyn->d_tag == DT_RELCOUNT)
roland 44874c
 		{
Mark Wielaard d10bca
@@ -1057,7 +1071,9 @@ section [%2d] '%s': DT_RELCOUNT used for
roland 44874c
 		      /* Does the number specified number of relative
roland 44874c
 			 relocations exceed the total number of
roland 44874c
 			 relocations?  */
roland 44874c
-		      if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
roland 44874c
+		      if (shdr->sh_entsize != 0
roland 44874c
+			  && dyn->d_un.d_val > (shdr->sh_size
roland 44874c
+						/ shdr->sh_entsize))
roland 44874c
 			ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
roland 44874c
 			       idx, section_name (ebl, idx),
Mark Wielaard d10bca
@@ -1217,7 +1233,8 @@ section [%2d] '%s': no relocations for m
roland 44874c
 	}
roland 44874c
     }
roland 44874c
 
roland 44874c
-  if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT))
roland 44874c
+  size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
roland 44874c
+  if (shdr->sh_entsize != sh_entsize)
roland 44874c
     ERROR (gettext (reltype == ELF_T_RELA ? "\
roland 44874c
 section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
roland 44874c
 section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
Mark Wielaard d10bca
@@ -1440,7 +1457,8 @@ check_rela (Ebl *ebl, GElf_Ehdr *ehdr, G
roland 44874c
   Elf_Data *symdata = elf_getdata (symscn, NULL);
roland 44874c
   enum load_state state = state_undecided;
roland 44874c
 
roland 44874c
-  for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 44874c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
roland 44874c
+  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
roland bf5b25
     {
roland 44874c
       GElf_Rela rela_mem;
roland 44874c
       GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
Mark Wielaard d10bca
@@ -1490,7 +1508,8 @@ check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GE
roland 44874c
   Elf_Data *symdata = elf_getdata (symscn, NULL);
roland 44874c
   enum load_state state = state_undecided;
roland 44874c
 
roland 44874c
-  for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 44874c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
roland 44874c
+  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
roland bf5b25
     {
roland 44874c
       GElf_Rel rel_mem;
roland 44874c
       GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
Mark Wielaard d10bca
@@ -1589,7 +1608,8 @@ section [%2d] '%s': referenced as string
roland 44874c
 	   shdr->sh_link, section_name (ebl, shdr->sh_link),
roland 44874c
 	   idx, section_name (ebl, idx));
roland bf5b25
 
roland 44874c
-  if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT))
roland 44874c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
roland 44874c
+  if (shdr->sh_entsize != sh_entsize)
roland 44874c
     ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
roland 44874c
 	   idx, section_name (ebl, idx));
Mark Wielaard d10bca
@@ -1599,7 +1619,7 @@ section [%2d] '%s': section entry size d
roland 44874c
 	   idx, section_name (ebl, idx));
roland 44874c
 
roland 44874c
   bool non_null_warned = false;
roland 44874c
-  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 44874c
+  for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
roland bf5b25
     {
roland 44874c
       GElf_Dyn dyn_mem;
roland 44874c
       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
Mark Wielaard d10bca
@@ -1871,6 +1891,8 @@ section [%2d] '%s': entry size does not
roland 44874c
 	   idx, section_name (ebl, idx));
roland 44874c
 
roland 44874c
   if (symshdr != NULL
roland 44874c
+      && shdr->sh_entsize
roland 44874c
+      && symshdr->sh_entsize
roland 44874c
       && (shdr->sh_size / shdr->sh_entsize
roland 44874c
 	  < symshdr->sh_size / symshdr->sh_entsize))
roland 44874c
     ERROR (gettext ("\
Mark Wielaard d10bca
@@ -1897,6 +1919,12 @@ section [%2d] '%s': extended section ind
roland 44874c
     }
roland 44874c
 
roland 44874c
   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
roland 44874c
+  if (data == NULL)
roland 44874c
+    {
roland 44874c
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
roland 44874c
+ 	     idx, section_name (ebl, idx));
roland 44874c
+      return;
roland 44874c
+    }
roland 44874c
 
roland 44874c
   if (*((Elf32_Word *) data->d_buf) != 0)
roland 44874c
     ERROR (gettext ("symbol 0 should have zero extended section index\n"));
Mark Wielaard d10bca
@@ -1939,7 +1967,7 @@ section [%2d] '%s': hash table section i
roland 44874c
 
roland 44874c
   size_t maxidx = nchain;
roland 44874c
 
roland 44874c
-  if (symshdr != NULL)
roland 44874c
+  if (symshdr != NULL && symshdr->sh_entsize != 0)
roland e76067
     {
roland 44874c
       size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
roland 44874c
 
Mark Wielaard d10bca
@@ -1950,18 +1978,28 @@ section [%2d] '%s': hash table section i
roland 44874c
       maxidx = symsize;
roland 44874c
     }
roland 44874c
 
roland 44874c
+  Elf32_Word *buf = (Elf32_Word *) data->d_buf;
roland 44874c
+  Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size);
roland 44874c
   size_t cnt;
roland 44874c
   for (cnt = 2; cnt < 2 + nbucket; ++cnt)
roland 44874c
-    if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
roland 44874c
+    {
roland 44874c
+      if (buf + cnt >= end)
roland 44874c
+	break;
roland 44874c
+      else if (buf[cnt] >= maxidx)
roland 44874c
       ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
roland 44874c
 	     idx, section_name (ebl, idx), cnt - 2);
roland 44874c
+    }
roland bf5b25
 
roland 44874c
   for (; cnt < 2 + nbucket + nchain; ++cnt)
roland 44874c
-    if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
roland 44874c
+    {
roland 44874c
+      if (buf + cnt >= end)
roland 44874c
+	break;
roland 44874c
+      else if (buf[cnt] >= maxidx)
roland 44874c
       ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': hash chain reference %zu out of bounds\n"),
roland 44874c
 	     idx, section_name (ebl, idx), cnt - 2 - nbucket);
roland 44874c
+    }
roland 44874c
 }
roland bf5b25
 
roland bf5b25
 
Mark Wielaard d10bca
@@ -1991,18 +2029,28 @@ section [%2d] '%s': hash table section i
roland 44874c
       maxidx = symsize;
roland 44874c
     }
roland 44874c
 
roland 44874c
+  Elf64_Xword *buf = (Elf64_Xword *) data->d_buf;
roland 44874c
+  Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size);
roland 44874c
   size_t cnt;
roland 44874c
   for (cnt = 2; cnt < 2 + nbucket; ++cnt)
roland 44874c
-    if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
roland 44874c
+    {
roland 44874c
+      if (buf + cnt >= end)
roland 44874c
+	break;
roland 44874c
+      else if (buf[cnt] >= maxidx)
roland 44874c
       ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
roland 44874c
 	     idx, section_name (ebl, idx), cnt - 2);
roland 44874c
+    }
roland bf5b25
 
roland 44874c
   for (; cnt < 2 + nbucket + nchain; ++cnt)
roland 44874c
-    if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
roland 44874c
+    {
roland 44874c
+      if (buf + cnt >= end)
roland 44874c
+	break;
roland 44874c
+      else if (buf[cnt] >= maxidx)
roland 44874c
       ERROR (gettext ("\
roland 44874c
 section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"),
roland 44874c
-	     idx, section_name (ebl, idx), (uint64_t) (cnt - 2 - nbucket));
roland 44874c
+	       idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket);
roland 44874c
+    }
roland 44874c
 }
roland 840723
 
roland bf5b25
 
Mark Wielaard d10bca
@@ -2027,7 +2075,7 @@ section [%2d] '%s': bitmask size not pow
roland 44874c
   if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))
roland bf5b25
     {
roland 44874c
       ERROR (gettext ("\
roland 44874c
-section [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"),
roland 44874c
+section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"),
roland 44874c
 	     idx, section_name (ebl, idx), (long int) shdr->sh_size,
roland 44874c
 	     (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)));
roland 44874c
       return;
Mark Wielaard d10bca
@@ -2699,8 +2747,9 @@ section [%2d] '%s' refers in sh_link to
roland bf5b25
 
roland 44874c
   /* The number of elements in the version symbol table must be the
roland 44874c
      same as the number of symbols.  */
roland 44874c
-  if (shdr->sh_size / shdr->sh_entsize
roland 44874c
-      != symshdr->sh_size / symshdr->sh_entsize)
roland 44874c
+  if (shdr->sh_entsize && symshdr->sh_entsize
roland 44874c
+      && (shdr->sh_size / shdr->sh_entsize
roland 44874c
+	  != symshdr->sh_size / symshdr->sh_entsize))
roland 44874c
     ERROR (gettext ("\
roland 44874c
 section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
roland 44874c
 	   idx, section_name (ebl, idx),
roland 5c16b0
--- elfutils/src/readelf.c
roland 5c16b0
+++ elfutils/src/readelf.c
Mark Wielaard d10bca
@@ -1183,6 +1183,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
roland bf5b25
 
roland 44874c
   GElf_Sym sym_mem;
roland 44874c
+  GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
roland 840723
+
roland 44874c
   printf ((grpref[0] & GRP_COMDAT)
roland 44874c
 	  ? ngettext ("\
roland 44874c
 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
Mark Wielaard d10bca
@@ -1195,8 +1197,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
 		      data->d_size / sizeof (Elf32_Word) - 1),
roland 44874c
 	  elf_ndxscn (scn),
roland 44874c
 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
roland 44874c
-	  elf_strptr (ebl->elf, symshdr->sh_link,
roland 44874c
-		      gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
roland 44874c
+	  (sym == NULL ? NULL
roland 44874c
+	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
roland 44874c
 	  ?: gettext ("<INVALID SYMBOL>"),
roland 44874c
 	  data->d_size / sizeof (Elf32_Word) - 1);
roland 840723
 
Mark Wielaard d10bca
@@ -1347,10 +1349,12 @@ static void
roland 44874c
 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
roland 44874c
 {
roland 44874c
   int class = gelf_getclass (ebl->elf);
roland 44874c
-  GElf_Shdr glink;
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink;
roland 44874c
   Elf_Data *data;
roland 44874c
   size_t cnt;
roland 44874c
   size_t shstrndx;
Mark J. Wielaard 22346c
+  size_t sh_entsize;
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
   /* Get the data of the section.  */
Mark J. Wielaard 22346c
   data = elf_getdata (scn, NULL);
Mark Wielaard d10bca
@@ -1362,21 +1366,26 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
roland 44874c
     error (EXIT_FAILURE, 0,
roland 44874c
 	   gettext ("cannot get section header string table index"));
roland bf5b25
 
Mark J. Wielaard 22346c
+  sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
Mark J. Wielaard 22346c
+
roland 44874c
+  glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	   elf_ndxscn (scn));
roland 840723
+
roland 44874c
   printf (ngettext ("\
roland 44874c
 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
roland 44874c
 		    "\
Mark J. Wielaard 22346c
 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
Mark J. Wielaard 22346c
-		    shdr->sh_size / shdr->sh_entsize),
Mark J. Wielaard 22346c
-	  (unsigned long int) (shdr->sh_size / shdr->sh_entsize),
Mark J. Wielaard 22346c
+		    shdr->sh_size / sh_entsize),
Mark J. Wielaard 22346c
+	  (unsigned long int) (shdr->sh_size / sh_entsize),
roland 44874c
 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
roland 44874c
 	  shdr->sh_offset,
roland 44874c
 	  (int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland 44874c
   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
roland 44874c
 
Mark J. Wielaard 22346c
-  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
Mark J. Wielaard 22346c
+  for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
Mark J. Wielaard 22346c
     {
Mark J. Wielaard 22346c
       GElf_Dyn dynmem;
Mark J. Wielaard 22346c
       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
Mark Wielaard d10bca
@@ -1525,7 +1534,8 @@ static void
Mark J. Wielaard 22346c
 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
Mark J. Wielaard 22346c
 {
Mark J. Wielaard 22346c
   int class = gelf_getclass (ebl->elf);
Mark J. Wielaard 22346c
-  int nentries = shdr->sh_size / shdr->sh_entsize;
Mark J. Wielaard 22346c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
Mark J. Wielaard 22346c
+  int nentries = shdr->sh_size / sh_entsize;
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
   /* Get the data of the section.  */
Mark J. Wielaard 22346c
   Elf_Data *data = elf_getdata (scn, NULL);
Mark Wielaard d10bca
@@ -1711,7 +1721,8 @@ static void
Mark J. Wielaard 22346c
 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
Mark J. Wielaard 22346c
 {
Mark J. Wielaard 22346c
   int class = gelf_getclass (ebl->elf);
Mark J. Wielaard 22346c
-  int nentries = shdr->sh_size / shdr->sh_entsize;
Mark J. Wielaard 22346c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
Mark J. Wielaard 22346c
+  int nentries = shdr->sh_size / sh_entsize;
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
   /* Get the data of the section.  */
Mark J. Wielaard 22346c
   Elf_Data *data = elf_getdata (scn, NULL);
Mark Wielaard d10bca
@@ -1958,6 +1969,13 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
     error (EXIT_FAILURE, 0,
roland 44874c
 	   gettext ("cannot get section header string table index"));
roland 44874c
 
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
+				   &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	   elf_ndxscn (scn));
roland 840723
+
roland 44874c
   /* Now we can compute the number of entries in the section.  */
roland 44874c
   unsigned int nsyms = data->d_size / (class == ELFCLASS32
roland 44874c
 				       ? sizeof (Elf32_Sym)
Mark Wielaard d10bca
@@ -1968,15 +1986,12 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
 		    nsyms),
roland 44874c
 	  (unsigned int) elf_ndxscn (scn),
roland 44874c
 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
roland 44874c
-  GElf_Shdr glink;
roland 44874c
   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
roland 44874c
 		    " %lu local symbols  String table: [%2u] '%s'\n",
roland 44874c
 		    shdr->sh_info),
roland 44874c
 	  (unsigned long int) shdr->sh_info,
roland 44874c
 	  (unsigned int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland 6b412c
 
roland 44874c
   fputs_unlocked (class == ELFCLASS32
roland 44874c
 		  ? gettext ("\
Mark Wielaard d10bca
@@ -2212,7 +2227,13 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
roland 44874c
     error (EXIT_FAILURE, 0,
roland 44874c
 	   gettext ("cannot get section header string table index"));
roland bf5b25
 
roland 44874c
-  GElf_Shdr glink;
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
+				   &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	   elf_ndxscn (scn));
roland 44874c
+
roland 44874c
   printf (ngettext ("\
roland 44874c
 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
roland 44874c
 		    "\
Mark Wielaard d10bca
@@ -2223,9 +2244,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
roland 44874c
 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
roland 44874c
 	  shdr->sh_offset,
roland 44874c
 	  (unsigned int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland 840723
 
roland 44874c
   unsigned int offset = 0;
roland 44874c
   for (int cnt = shdr->sh_info; --cnt >= 0; )
Mark Wielaard d10bca
@@ -2278,8 +2297,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
     error (EXIT_FAILURE, 0,
roland 44874c
 	   gettext ("cannot get section header string table index"));
roland 44874c
 
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
+				   &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	   elf_ndxscn (scn));
roland 840723
+
roland 44874c
   int class = gelf_getclass (ebl->elf);
roland 44874c
-  GElf_Shdr glink;
roland 44874c
   printf (ngettext ("\
roland 44874c
 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
roland 44874c
 		    "\
Mark Wielaard d10bca
@@ -2291,9 +2316,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
roland 44874c
 	  shdr->sh_offset,
roland 44874c
 	  (unsigned int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland 44874c
 
roland 44874c
   unsigned int offset = 0;
roland 44874c
   for (int cnt = shdr->sh_info; --cnt >= 0; )
Mark Wielaard d10bca
@@ -2555,25 +2578,30 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
roland 44874c
       filename = NULL;
roland 44874c
     }
roland 44874c
 
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
+				   &glink_mem);
Mark J. Wielaard 22346c
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	   elf_ndxscn (scn));
roland 840723
+
roland 44874c
   /* Print the header.  */
roland 44874c
-  GElf_Shdr glink;
roland 44874c
   printf (ngettext ("\
roland 44874c
 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
roland 44874c
 		    "\
Mark J. Wielaard 22346c
 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
Mark J. Wielaard 22346c
-		    shdr->sh_size / shdr->sh_entsize),
Mark J. Wielaard 22346c
+		    shdr->sh_size / sh_entsize),
Mark J. Wielaard 22346c
 	  (unsigned int) elf_ndxscn (scn),
Mark J. Wielaard 22346c
 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
Mark J. Wielaard 22346c
-	  (int) (shdr->sh_size / shdr->sh_entsize),
Mark J. Wielaard 22346c
+	  (int) (shdr->sh_size / sh_entsize),
roland 44874c
 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
roland 44874c
 	  shdr->sh_offset,
roland 44874c
 	  (unsigned int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland bf5b25
 
roland 44874c
   /* Now we can finally look at the actual contents of this section.  */
Mark J. Wielaard 22346c
-  for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
Mark J. Wielaard 22346c
+  for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
Mark J. Wielaard 22346c
     {
Mark J. Wielaard 22346c
       if (cnt % 2 == 0)
Mark J. Wielaard 22346c
 	printf ("\n %4d:", cnt);
Mark Wielaard d10bca
@@ -2622,7 +2650,17 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn,
roland 44874c
   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
roland 44874c
     ++counts[lengths[cnt]];
roland bf5b25
 
roland 44874c
-  GElf_Shdr glink;
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
roland 44874c
+					       shdr->sh_link),
roland 44874c
+				   &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    {
roland 44874c
+      error (0, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	     elf_ndxscn (scn));
roland 44874c
+      return;
roland 44874c
+    }
roland 44874c
+
roland 44874c
   printf (ngettext ("\
roland 44874c
 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
roland 44874c
 		    "\
Mark Wielaard d10bca
@@ -2635,9 +2673,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn,
roland 44874c
 	  shdr->sh_addr,
roland 44874c
 	  shdr->sh_offset,
roland 44874c
 	  (unsigned int) shdr->sh_link,
roland 44874c
-	  elf_strptr (ebl->elf, shstrndx,
roland 44874c
-		      gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
roland 44874c
-				    &glink)->sh_name));
roland 44874c
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
roland 840723
 
roland 44874c
   if (extrastr != NULL)
roland 44874c
     fputs (extrastr, stdout);
Mark Wielaard d10bca
@@ -2897,7 +2933,8 @@ print_liblist (Ebl *ebl)
Mark J. Wielaard 22346c
 
Mark J. Wielaard 22346c
       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
Mark J. Wielaard 22346c
 	{
Mark J. Wielaard 22346c
-	  int nentries = shdr->sh_size / shdr->sh_entsize;
Mark J. Wielaard 22346c
+	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
Mark J. Wielaard 22346c
+	  int nentries = shdr->sh_size / sh_entsize;
Mark J. Wielaard 22346c
 	  printf (ngettext ("\
Mark J. Wielaard 22346c
 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
Mark J. Wielaard 22346c
 			    "\
Mark Wielaard d10bca
@@ -4644,6 +4681,16 @@ print_debug_aranges_section (Dwfl_Module
roland 44874c
       return;
roland 44874c
     }
roland 44874c
 
roland 44874c
+  GElf_Shdr glink_mem;
roland 44874c
+  GElf_Shdr *glink;
roland 44874c
+  glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
roland 44874c
+  if (glink == NULL)
roland 44874c
+    {
roland 44874c
+      error (0, 0, gettext ("invalid sh_link value in section %Zu"),
roland 44874c
+	     elf_ndxscn (scn));
roland 44874c
+      return;
roland 44874c
+    }
roland 44874c
+
roland 44874c
   printf (ngettext ("\
roland 5c16b0
 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
roland 44874c
 		    "\
roland 5c16b0
--- elfutils/src/strip.c
roland 5c16b0
+++ elfutils/src/strip.c
Mark Wielaard d10bca
@@ -564,6 +564,11 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
       goto fail_close;
roland 44874c
     }
roland bf5b25
 
roland 44874c
+  if (shstrndx >= shnum)
roland 44874c
+    goto illformed;
roland 44874c
+
roland 44874c
+#define elf_assert(test) do { if (!(test)) goto illformed; } while (0)
roland 44874c
+
roland 44874c
   /* Storage for section information.  We leave room for two more
roland 44874c
      entries since we unconditionally create a section header string
roland 44874c
      table.  Maybe some weird tool created an ELF file without one.
Mark Wielaard d10bca
@@ -585,7 +590,7 @@ handle_elf (int fd, Elf *elf, const char
roland 6b412c
     {
roland 44874c
       /* This should always be true (i.e., there should not be any
roland 44874c
 	 holes in the numbering).  */
roland 44874c
-      assert (elf_ndxscn (scn) == cnt);
roland 44874c
+      elf_assert (elf_ndxscn (scn) == cnt);
roland bf5b25
 
roland 44874c
       shdr_info[cnt].scn = scn;
roland bf5b25
 
Mark Wielaard d10bca
@@ -598,6 +603,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 					shdr_info[cnt].shdr.sh_name);
roland 44874c
       if (shdr_info[cnt].name == NULL)
roland 6b412c
 	{
roland 44874c
+	illformed:
roland 44874c
 	  error (0, 0, gettext ("illformed file '%s'"), fname);
roland 44874c
 	  goto fail_close;
roland 44874c
 	}
Mark Wielaard d10bca
@@ -607,6 +613,8 @@ handle_elf (int fd, Elf *elf, const char
roland bf5b25
 
roland 44874c
       /* Remember the shdr.sh_link value.  */
roland 44874c
       shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
roland 44874c
+      if (shdr_info[cnt].old_sh_link >= shnum)
roland 44874c
+	goto illformed;
roland 840723
 
roland 44874c
       /* Sections in files other than relocatable object files which
roland 44874c
 	 are not loaded can be freely moved by us.  In relocatable
Mark Wielaard d10bca
@@ -619,7 +627,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	 appropriate reference.  */
roland 44874c
       if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
roland 44874c
 	{
roland 44874c
-	  assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
roland 44874c
+	  elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
roland 44874c
 	  shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
roland 840723
 	}
roland 44874c
       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
Mark Wielaard d10bca
@@ -636,7 +644,12 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	  for (inner = 1;
roland 44874c
 	       inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
roland 44874c
 	       ++inner)
roland 44874c
+	    {
roland 44874c
+	      if (grpref[inner] < shnum)
roland 44874c
 	    shdr_info[grpref[inner]].group_idx = cnt;
roland 44874c
+	      else
roland 44874c
+		goto illformed;
roland 44874c
+	    }
roland bf5b25
 
roland 44874c
 	  if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
roland 44874c
 	    /* If the section group contains only one element and this
Mark Wielaard d10bca
@@ -647,7 +660,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	}
roland 44874c
       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
roland 840723
 	{
roland 44874c
-	  assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
roland 44874c
+	  elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
roland 44874c
 	  shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
roland 44874c
 	}
roland bf5b25
 
Mark Wielaard d10bca
@@ -655,7 +668,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	 discarded right away.  */
roland 44874c
       if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
roland 840723
 	{
roland 44874c
-	  assert (shdr_info[cnt].group_idx != 0);
roland 44874c
+	  elf_assert (shdr_info[cnt].group_idx != 0);
roland 840723
 
roland 44874c
 	  if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
roland 44874c
 	    {
Mark Wielaard d10bca
@@ -731,10 +744,14 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	    {
roland 44874c
 	      /* If a relocation section is marked as being removed make
roland 44874c
 		 sure the section it is relocating is removed, too.  */
roland 44874c
-	      if ((shdr_info[cnt].shdr.sh_type == SHT_REL
roland 44874c
+	      if (shdr_info[cnt].shdr.sh_type == SHT_REL
roland 44874c
 		   || shdr_info[cnt].shdr.sh_type == SHT_RELA)
roland 44874c
-		  && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
Mark J. Wielaard 22346c
-		shdr_info[cnt].idx = 1;
roland 44874c
+		{
roland 44874c
+		  if (shdr_info[cnt].shdr.sh_info >= shnum)
roland 44874c
+		    goto illformed;
roland 44874c
+		  else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
Mark J. Wielaard 22346c
+		    shdr_info[cnt].idx = 1;
Mark J. Wielaard 22346c
+		}
roland 840723
 
Mark J. Wielaard 22346c
 	      /* If a group section is marked as being removed make
Mark J. Wielaard 22346c
 		 sure all the sections it contains are being removed, too.  */
Mark Wielaard d10bca
@@ -778,7 +795,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		  if (shdr_info[cnt].symtab_idx != 0
roland 44874c
 		      && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
roland 44874c
 		    {
roland 44874c
-		      assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
roland 44874c
+		      elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
roland 44874c
 
roland 44874c
 		      shdr_info[shdr_info[cnt].symtab_idx].data
roland 44874c
 			= elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
Mark Wielaard d10bca
@@ -818,6 +835,9 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		      else if (scnidx == SHN_XINDEX)
roland 44874c
 			scnidx = xndx;
roland 44874c
 
roland 44874c
+		      if (scnidx >= shnum)
roland 44874c
+			goto illformed;
roland 44874c
+
roland 44874c
 		      if (shdr_info[scnidx].idx == 0)
roland 44874c
 			/* This symbol table has a real symbol in
roland 44874c
 			   a discarded section.  So preserve the
Mark Wielaard d10bca
@@ -848,12 +868,16 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		}
roland 44874c
 
roland 44874c
 	      /* Handle references through sh_info.  */
roland 44874c
-	      if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
roland 44874c
-		  && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
roland 44874c
+	      if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
roland 44874c
+		{
roland 44874c
+		  if (shdr_info[cnt].shdr.sh_info >= shnum)
roland 44874c
+		    goto illformed;
roland 44874c
+		  else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
roland 44874c
 		{
roland 44874c
 		  shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
roland 44874c
 		  changes |= shdr_info[cnt].shdr.sh_info < cnt;
roland 44874c
 		}
roland 44874c
+		}
roland 44874c
 
roland 44874c
 	      /* Mark the section as investigated.  */
roland 44874c
 	      shdr_info[cnt].idx = 2;
Mark Wielaard d10bca
@@ -994,7 +1018,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	  error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
roland 44874c
 		 elf_errmsg (-1));
roland 44874c
 
roland 44874c
-	assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
roland 44874c
+	elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
roland 44874c
 
roland 44874c
 	/* Add this name to the section header string table.  */
roland 44874c
 	shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
Mark Wielaard d10bca
@@ -1031,7 +1055,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	error (EXIT_FAILURE, 0,
roland 44874c
 	       gettext ("while create section header section: %s"),
roland 44874c
 	       elf_errmsg (-1));
roland 44874c
-      assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
roland 44874c
+      elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
roland 44874c
 
roland 44874c
       shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
roland 44874c
       if (shdr_info[cnt].data == NULL)
Mark Wielaard d10bca
@@ -1087,7 +1111,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
     error (EXIT_FAILURE, 0,
roland 44874c
 	   gettext ("while create section header section: %s"),
roland 44874c
 	   elf_errmsg (-1));
roland 44874c
-  assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
roland 44874c
+  elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
roland 44874c
 
roland 44874c
   /* Finalize the string table and fill in the correct indices in the
roland 44874c
      section headers.  */
Mark Wielaard d10bca
@@ -1177,20 +1201,20 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		    shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
roland 44874c
 					     NULL);
roland 840723
 
roland 44874c
-		    assert ((versiondata->d_size / sizeof (Elf32_Word))
roland 44874c
+		    elf_assert ((versiondata->d_size / sizeof (Elf32_Word))
roland 44874c
 			    >= shdr_info[cnt].data->d_size / elsize);
roland 44874c
 		  }
roland 840723
 
roland 44874c
 		if (shdr_info[cnt].version_idx != 0)
roland 44874c
 		  {
roland 44874c
-		    assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
roland 44874c
+		    elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
roland 44874c
 		    /* This section has associated version
roland 44874c
 		       information.  We have to modify that
roland 44874c
 		       information, too.  */
roland 44874c
 		    versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
roland 44874c
 					       NULL);
roland 840723
 
roland 44874c
-		    assert ((versiondata->d_size / sizeof (GElf_Versym))
roland 44874c
+		    elf_assert ((versiondata->d_size / sizeof (GElf_Versym))
roland 44874c
 			    >= shdr_info[cnt].data->d_size / elsize);
roland 44874c
 		  }
roland bf5b25
 
Mark Wielaard d10bca
@@ -1245,7 +1269,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		      sec = shdr_info[sym->st_shndx].idx;
roland 44874c
 		    else
roland 44874c
 		      {
roland 44874c
-			assert (shndxdata != NULL);
roland 44874c
+			elf_assert (shndxdata != NULL);
roland 840723
 
roland 44874c
 			sec = shdr_info[xshndx].idx;
roland 44874c
 		      }
Mark Wielaard d10bca
@@ -1266,7 +1290,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 			    nxshndx = sec;
roland 44874c
 			  }
roland 840723
 
roland 44874c
-			assert (sec < SHN_LORESERVE || shndxdata != NULL);
roland 44874c
+			elf_assert (sec < SHN_LORESERVE || shndxdata != NULL);
roland 840723
 
roland 44874c
 			if ((inner != destidx || nshndx != sym->st_shndx
roland 44874c
 			     || (shndxdata != NULL && nxshndx != xshndx))
Mark Wielaard d10bca
@@ -1293,9 +1317,11 @@ handle_elf (int fd, Elf *elf, const char
Mark J. Wielaard 22346c
 		      {
Mark J. Wielaard 22346c
 			size_t sidx = (sym->st_shndx != SHN_XINDEX
Mark J. Wielaard 22346c
 					? sym->st_shndx : xshndx);
Mark J. Wielaard 22346c
-			assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
Mark J. Wielaard 22346c
-				|| (shdr_info[sidx].shdr.sh_type == SHT_GROUP
Mark J. Wielaard 22346c
-				    && shdr_info[sidx].shdr.sh_info == inner));
Mark J. Wielaard 22346c
+			elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
Mark J. Wielaard 22346c
+				    || ((shdr_info[sidx].shdr.sh_type
Mark J. Wielaard 22346c
+					 == SHT_GROUP)
Mark J. Wielaard 22346c
+					&& (shdr_info[sidx].shdr.sh_info
Mark J. Wielaard 22346c
+					    == inner)));
Mark J. Wielaard 22346c
 		      }
roland 44874c
 		  }
roland 840723
 
Mark Wielaard d10bca
@@ -1483,11 +1509,11 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		  {
roland 44874c
 		    GElf_Sym sym_mem;
roland 44874c
 		    GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
roland 44874c
-		    assert (sym != NULL);
roland 44874c
+		    elf_assert (sym != NULL);
roland bf5b25
 
roland 44874c
 		    const char *name = elf_strptr (elf, strshndx,
roland 44874c
 						   sym->st_name);
roland 44874c
-		    assert (name != NULL);
roland 44874c
+		    elf_assert (name != NULL);
roland 44874c
 		    size_t hidx = elf_hash (name) % nbucket;
roland bf5b25
 
roland 44874c
 		    if (bucket[hidx] == 0)
Mark Wielaard d10bca
@@ -1506,8 +1532,8 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 	    else
roland 44874c
 	      {
roland 44874c
 		/* Alpha and S390 64-bit use 64-bit SHT_HASH entries.  */
roland 44874c
-		assert (shdr_info[cnt].shdr.sh_entsize
Mark J. Wielaard 22346c
-			== sizeof (Elf64_Xword));
roland 44874c
+		elf_assert (shdr_info[cnt].shdr.sh_entsize
Mark J. Wielaard 22346c
+                            == sizeof (Elf64_Xword));
roland bf5b25
 
roland 44874c
 		Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
Mark J. Wielaard 22346c
 
Mark Wielaard d10bca
@@ -1537,11 +1563,11 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 		  {
roland 44874c
 		    GElf_Sym sym_mem;
roland 44874c
 		    GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
roland 44874c
-		    assert (sym != NULL);
roland 44874c
+		    elf_assert (sym != NULL);
roland bf5b25
 
roland 44874c
 		    const char *name = elf_strptr (elf, strshndx,
roland 44874c
 						   sym->st_name);
roland 44874c
-		    assert (name != NULL);
roland 44874c
+		    elf_assert (name != NULL);
roland 44874c
 		    size_t hidx = elf_hash (name) % nbucket;
roland 44874c
 
roland 44874c
 		    if (bucket[hidx] == 0)