roland 5c16b0
--- elfutils/libelf/ChangeLog
roland 5c16b0
+++ elfutils/libelf/ChangeLog
roland 0f58b0
@@ -649,10 +649,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
roland f790d2
@@ -114,6 +114,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.
roland 44874c
    This file is part of Red Hat elfutils.
roland 44874c
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
roland 44874c
 
roland 5c16b0
@@ -81,7 +81,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
 
roland 5c16b0
@@ -98,6 +99,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
roland 8cafad
@@ -135,6 +135,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
roland 8cafad
@@ -223,6 +223,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
roland 8cafad
@@ -645,6 +648,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
roland 5c16b0
@@ -165,7 +165,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
 
roland 5c16b0
@@ -213,7 +214,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
 
roland 5c16b0
@@ -285,6 +287,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)
roland f790d2
@@ -324,6 +335,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
 
roland f790d2
@@ -410,6 +431,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
roland 44874c
@@ -179,6 +179,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
roland d36848
@@ -125,10 +125,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
roland d36848
@@ -163,10 +178,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
roland 44874c
@@ -104,10 +104,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland e4d1f5
@@ -93,7 +93,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;
roland e4d1f5
@@ -114,7 +114,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
roland e4d1f5
 
roland e4d1f5
@@ -86,7 +86,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland e4d1f5
@@ -83,7 +83,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -71,12 +71,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);
roland e4d1f5
@@ -93,7 +87,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;
roland e4d1f5
@@ -114,7 +108,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -71,12 +71,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);
roland e4d1f5
@@ -93,7 +87,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;
roland e4d1f5
@@ -113,7 +107,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
roland e4d1f5
 
roland e4d1f5
@@ -90,7 +90,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;
roland e4d1f5
@@ -119,7 +119,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland e4d1f5
@@ -84,7 +84,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland e4d1f5
@@ -90,7 +90,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;
roland e4d1f5
@@ -110,7 +110,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;
roland e4d1f5
@@ -139,7 +139,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
roland e4d1f5
 
roland e4d1f5
@@ -92,7 +92,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -71,12 +71,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.  */
roland e4d1f5
@@ -102,7 +96,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;
roland e4d1f5
@@ -116,7 +110,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
roland e4d1f5
 
roland 44874c
@@ -68,12 +68,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
     {
roland e4d1f5
@@ -87,7 +81,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland e4d1f5
@@ -75,8 +75,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -68,12 +68,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.  */
roland e4d1f5
@@ -101,7 +95,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;
roland e4d1f5
@@ -117,7 +111,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -68,12 +68,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.  */
roland e4d1f5
@@ -99,7 +93,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;
roland e4d1f5
@@ -114,7 +108,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -72,12 +72,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.  */
roland e4d1f5
@@ -102,7 +96,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;
roland e4d1f5
@@ -125,7 +119,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -72,12 +72,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.  */
roland e4d1f5
@@ -93,7 +87,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
roland e4d1f5
 
roland 44874c
@@ -77,12 +77,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.  */
roland e4d1f5
@@ -128,7 +122,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;
roland e4d1f5
@@ -151,7 +145,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.
roland e4d1f5
    This file is part of Red Hat elfutils.
roland e4d1f5
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
roland e4d1f5
 
roland e4d1f5
@@ -75,8 +75,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
roland 8cafad
@@ -608,4 +608,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
roland 0f58b0
@@ -1615,6 +1615,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.
roland 0f58b0
@@ -1660,6 +1670,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
roland ba5f20
@@ -131,6 +131,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[])
roland ba5f20
@@ -319,10 +323,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
 
roland ba5f20
@@ -344,11 +357,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
 {
roland ba5f20
@@ -632,7 +640,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));
roland ba5f20
@@ -670,7 +679,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)
roland ba5f20
@@ -690,7 +699,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)
roland ba5f20
@@ -1038,9 +1048,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);
roland ba5f20
@@ -1050,7 +1062,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
 		{
roland ba5f20
@@ -1064,7 +1078,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),
roland ba5f20
@@ -1224,7 +1240,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"),
roland ba5f20
@@ -1447,7 +1464,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);
roland ba5f20
@@ -1497,7 +1515,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);
roland ba5f20
@@ -1600,7 +1619,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));
roland ba5f20
@@ -1610,7 +1630,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);
roland ba5f20
@@ -1891,6 +1911,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 ("\
roland ba5f20
@@ -1917,6 +1939,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"));
roland ba5f20
@@ -1959,7 +1987,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
 
roland ba5f20
@@ -1970,18 +1998,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
 
roland ba5f20
@@ -2011,18 +2049,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
 
roland ba5f20
@@ -2047,7 +2095,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;
roland ba5f20
@@ -2719,8 +2767,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
roland 0f58b0
@@ -1172,6 +1172,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",
roland 0f58b0
@@ -1184,8 +1186,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
 
roland 0f58b0
@@ -1336,7 +1338,8 @@ 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;
roland 0f58b0
@@ -1351,6 +1354,11 @@ 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
 
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
 		    "\
roland 0f58b0
@@ -1360,9 +1368,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, 
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
 
roland 44874c
   for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 0f58b0
@@ -1945,6 +1951,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)
roland 0f58b0
@@ -1955,15 +1968,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 ("\
roland 0f58b0
@@ -2199,7 +2209,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
 		    "\
roland 0f58b0
@@ -2210,9 +2226,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; )
roland 0f58b0
@@ -2265,8 +2279,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
 		    "\
roland 0f58b0
@@ -2278,9 +2298,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; )
roland 0f58b0
@@ -2542,8 +2560,14 @@ 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);
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
 		    "\
roland 0f58b0
@@ -2555,9 +2579,7 @@ handle_versym (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 bf5b25
 
roland 44874c
   /* Now we can finally look at the actual contents of this section.  */
roland 44874c
   for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
roland 0f58b0
@@ -2609,7 +2631,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
 		    "\
roland 0f58b0
@@ -2622,9 +2654,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);
roland 0f58b0
@@ -4312,6 +4342,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
roland ba5f20
@@ -545,6 +545,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.
roland ba5f20
@@ -566,7 +571,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
 
roland ba5f20
@@ -579,6 +584,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
 	}
roland ba5f20
@@ -588,6 +594,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
roland ba5f20
@@ -600,7 +608,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))
roland ba5f20
@@ -617,7 +625,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
roland ba5f20
@@ -628,7 +641,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
 
roland ba5f20
@@ -636,7 +649,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
 	    {
roland ba5f20
@@ -711,11 +724,15 @@ 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)
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
 		shdr_info[cnt].idx = 1;
roland 44874c
 	    }
roland 44874c
+	    }
roland 840723
 
roland 44874c
 	  if (shdr_info[cnt].idx == 1)
roland 44874c
 	    {
roland ba5f20
@@ -742,7 +759,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,
roland ba5f20
@@ -782,6 +799,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
roland ba5f20
@@ -812,12 +832,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;
roland ba5f20
@@ -956,7 +980,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);
roland ba5f20
@@ -993,7 +1017,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)
roland ba5f20
@@ -1049,7 +1073,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.  */
roland ba5f20
@@ -1139,20 +1163,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
 
roland ba5f20
@@ -1207,7 +1231,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
 		      }
roland ba5f20
@@ -1228,7 +1252,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))
roland ba5f20
@@ -1252,7 +1276,7 @@ handle_elf (int fd, Elf *elf, const char
roland 44874c
 			     || shdr_info[cnt].debug_data == NULL)
roland 44874c
 		      /* This is a section symbol for a section which has
roland 44874c
 			 been removed.  */
roland 44874c
-		      assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
roland 44874c
+		      elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
roland 44874c
 		  }
roland 840723
 
roland 44874c
 		if (destidx != inner)
roland ba5f20
@@ -1439,11 +1463,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)
roland ba5f20
@@ -1462,7 +1486,7 @@ 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
roland 44874c
+		elf_assert (shdr_info[cnt].shdr.sh_entsize
roland 44874c
 			== sizeof (Elf64_Xword));
roland bf5b25
 
roland 44874c
 		Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
roland ba5f20
@@ -1493,11 +1517,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)