[PATCH] elflint: Add various low-level checks.

Mark Wielaard mjw at redhat.com
Wed Dec 31 00:02:37 UTC 2014


elflint could crash or hang because it didn't check some low level issues.

https://bugzilla.redhat.com/show_bug.cgi?id=1170810

Reported-by: Alexander Cherepanov <cherepan at mccme.ru>
Signed-off-by: Mark Wielaard <mjw at redhat.com>
---
 src/ChangeLog |  23 ++++++
 src/elflint.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 208 insertions(+), 48 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 66d6270..f8fd947 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,26 @@
+2014-12-30  Mark Wielaard  <mjw at redhat.com>
+
+	* elflint.c (check_scn_group): Check d_buf and name are not NULL.
+	(is_rel_dyn): Check d is not NULL. Check shdr->sh_entsize is not
+	zero.
+	(check_dynamic): Check strshdr is not NULL. Check d_tag is positive.
+	(check_symtab_shndx): Check symshdr and data->d_buf are not NULL.
+	Check shdr and symshdr sh_entsize are not zero.
+	(check_gnu_hash): Make sure maskidx is smaller than bitmask_words.
+	Check symshdr->sh_entsize is not zero. Check data->d_buf is not
+	NULL.
+	(compare_hash_gnu_hash): Check sections d_buf are not NULL.
+	Check section data is large enough. Use gnu_symbias.
+	(check_group): Check section val is valid.
+	(has_copy_reloc): Check sh_entsize is not zero.
+	(check_versym): Likewise.
+	(unknown_dependency_p): Likewise.
+	(check_verneed): Break on invalid ref or offset. Don't assert.
+	(check_attributes): Make sure d_buf is not NULL.
+	(check_note): Likewise.
+	(check_note_section): Likewise.
+	(check_program_header): Make sure section name is not NULL.
+
 2014-12-26  Mark Wielaard  <mjw at redhat.com>
 
 	* strings.c (read_elf): Produce error when section data falls outside
diff --git a/src/elflint.c b/src/elflint.c
index 7e73253..6bb49a9 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -554,7 +554,8 @@ check_scn_group (Ebl *ebl, int idx)
 	    continue;
 
 	  Elf_Data *data = elf_getdata (scn, NULL);
-	  if (data == NULL || data->d_size < sizeof (Elf32_Word))
+	  if (data == NULL || data->d_buf == NULL
+	      || data->d_size < sizeof (Elf32_Word))
 	    /* Cannot check the section.  */
 	    continue;
 
@@ -692,8 +693,8 @@ section [%2d] '%s': symbol %zu: invalid name value\n"),
       else
 	{
 	  name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
-	  assert (name != NULL
-		  || strshdr->sh_type != SHT_STRTAB);
+	  if (name == NULL)
+	    name = "";
 	}
 
       if (sym->st_shndx == SHN_XINDEX)
@@ -1061,12 +1062,17 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
       if (rcshdr == NULL)
 	break;
 
-      if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize)
+      if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize != 0)
 	{
 	  /* Found the dynamic section.  Look through it.  */
 	  Elf_Data *d = elf_getdata (scn, NULL);
 	  size_t cnt;
 
+	  if (d == NULL)
+	    ERROR (gettext ("\
+section [%2d] '%s': cannot get section data.\n"),
+		   idx, section_name (ebl, idx));
+
 	  for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt)
 	    {
 	      GElf_Dyn dyn_mem;
@@ -1099,7 +1105,7 @@ section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
 			 relative.  */
 		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
 								   idx), NULL);
-		      if (reldata != NULL)
+		      if (reldata != NULL && shdr->sh_entsize != 0)
 			for (size_t inner = 0;
 			     inner < shdr->sh_size / shdr->sh_entsize;
 			     ++inner)
@@ -1141,7 +1147,8 @@ section [%2d] '%s': DT_RELACOUNT used for this REL section\n"),
 		      /* Does the number specified number of relative
 			 relocations exceed the total number of
 			 relocations?  */
-		      if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
+		      if (shdr->sh_entsize != 0
+			  && dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
 			ERROR (gettext ("\
 section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
 			       idx, section_name (ebl, idx),
@@ -1151,7 +1158,7 @@ section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
 			 relative.  */
 		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
 								   idx), NULL);
-		      if (reldata != NULL)
+		      if (reldata != NULL && shdr->sh_entsize != 0)
 			for (size_t inner = 0;
 			     inner < shdr->sh_size / shdr->sh_entsize;
 			     ++inner)
@@ -1284,7 +1291,7 @@ section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
 	  GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
 	  Elf_Data *dyndata = elf_getdata (dynscn, NULL);
 	  if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
-	      && dyndata != NULL)
+	      && dyndata != NULL && dynshdr->sh_entsize != 0)
 	    for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
 	      {
 		GElf_Dyn dyn_mem;
@@ -1622,6 +1629,13 @@ check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
 section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
 	   shdr->sh_link, section_name (ebl, shdr->sh_link),
 	   idx, section_name (ebl, idx));
+  else if (strshdr == NULL)
+    {
+      ERROR (gettext ("\
+section [%2d]: referenced as string table for section [%2d] '%s' but section link value is invalid\n"),
+	   shdr->sh_link, idx, section_name (ebl, idx));
+      return;
+    }
 
   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
   if (shdr->sh_entsize != sh_entsize)
@@ -1685,10 +1699,10 @@ section [%2d] '%s': entry %zu: level 2 tag %s used\n"),
 
 	  has_dt[dyn->d_tag] = true;
 	}
-      else if (dyn->d_tag <= DT_VALRNGHI
+      else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_VALRNGHI
 	       && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
 	has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true;
-      else if (dyn->d_tag <= DT_ADDRRNGHI
+      else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_ADDRRNGHI
 	       && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
 	has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true;
 
@@ -1896,6 +1910,10 @@ section [%2d] '%s': only relocatable files can have extended section index\n"),
     ERROR (gettext ("\
 section [%2d] '%s': extended section index section not for symbol table\n"),
 	   idx, section_name (ebl, idx));
+  else if (symshdr == NULL)
+    ERROR (gettext ("\
+section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"),
+	   idx, section_name (ebl, idx), shdr->sh_link);
   Elf_Data *symdata = elf_getdata (symscn, NULL);
   if (symdata == NULL)
     ERROR (gettext ("cannot get data for symbol section\n"));
@@ -1906,8 +1924,8 @@ section [%2d] '%s': entry size does not match Elf32_Word\n"),
 	   idx, section_name (ebl, idx));
 
   if (symshdr != NULL
-      && shdr->sh_entsize
-      && symshdr->sh_entsize
+      && shdr->sh_entsize != 0
+      && symshdr->sh_entsize != 0
       && (shdr->sh_size / shdr->sh_entsize
 	  < symshdr->sh_size / symshdr->sh_entsize))
     ERROR (gettext ("\
@@ -1934,7 +1952,7 @@ section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same
     }
 
   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
-  if (data == NULL)
+  if (data == NULL || data->d_buf == NULL)
     {
       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
 	     idx, section_name (ebl, idx));
@@ -2033,7 +2051,7 @@ section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
 
   size_t maxidx = nchain;
 
-  if (symshdr != NULL)
+  if (symshdr != NULL && shdr->sh_entsize != 0)
     {
       size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
 
@@ -2104,7 +2122,7 @@ section [%2d] '%s': 2nd hash function shift too big: %u\n"),
   size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words
 							 + nbuckets);
 
-  if (symshdr != NULL)
+  if (symshdr != NULL && symshdr->sh_entsize != 0)
     maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize);
 
   /* We need the symbol section data.  */
@@ -2155,8 +2173,10 @@ section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"
 		       idx, section_name (ebl, idx), symidx,
 		       cnt - (4 + bitmask_words));
 
-	      const char *symname = elf_strptr (ebl->elf, symshdr->sh_link,
-						sym->st_name);
+	      const char *symname = (sym != NULL
+				     ? elf_strptr (ebl->elf, symshdr->sh_link,
+						   sym->st_name)
+				     : NULL);
 	      if (symname != NULL)
 		{
 		  Elf32_Word hval = elf_gnu_hash (symname);
@@ -2168,6 +2188,14 @@ section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
 
 		  /* Set the bits in the bitmask.  */
 		  size_t maskidx = (hval / classbits) & bitmask_idxmask;
+		  if (maskidx >= bitmask_words)
+		    {
+		      ERROR (gettext ("\
+section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"),
+			     idx, section_name (ebl, idx), symidx,
+			     cnt - (4 + bitmask_words));
+		      return;
+		    }
 		  if (classbits == 32)
 		    {
 		      collected.p32[maskidx]
@@ -2195,7 +2223,7 @@ section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
 	ERROR (gettext ("\
 section [%2d] '%s': hash chain for bucket %zu out of bounds\n"),
 	       idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
-      else if (symshdr != NULL
+      else if (symshdr != NULL && symshdr->sh_entsize != 0
 	       && symidx > symshdr->sh_size / symshdr->sh_entsize)
 	ERROR (gettext ("\
 section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"),
@@ -2223,7 +2251,7 @@ section [%2d] '%s': relocatable files cannot have hash tables\n"),
     }
 
   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
-  if (data == NULL)
+  if (data == NULL || data->d_buf == NULL)
     {
       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
 	     idx, section_name (ebl, idx));
@@ -2237,6 +2265,10 @@ section [%2d] '%s': relocatable files cannot have hash tables\n"),
     ERROR (gettext ("\
 section [%2d] '%s': hash table not for dynamic symbol table\n"),
 	   idx, section_name (ebl, idx));
+  else if (symshdr == NULL)
+    ERROR (gettext ("\
+section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"),
+	   idx, section_name (ebl, idx), shdr->sh_link);
 
   if (shdr->sh_entsize != (tag == SHT_GNU_HASH
 			   ? (gelf_getclass (ebl->elf) == ELFCLASS32
@@ -2292,7 +2324,8 @@ compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx,
   GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem);
 
   if (hash_shdr == NULL || gnu_hash_shdr == NULL
-      || hash_data == NULL || gnu_hash_data == NULL)
+      || hash_data == NULL || hash_data->d_buf == NULL
+      || gnu_hash_data == NULL || gnu_hash_data->d_buf == NULL)
     /* None of these pointers should be NULL since we used the
        sections already.  We are careful nonetheless.  */
     return;
@@ -2313,27 +2346,70 @@ sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
   GElf_Shdr sym_shdr_mem;
   GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem);
 
-  if (sym_data == NULL || sym_shdr == NULL)
+  if (sym_data == NULL || sym_data->d_buf == NULL
+      || sym_shdr == NULL || sym_shdr->sh_entsize == 0)
     return;
 
-  int nentries = sym_shdr->sh_size / sym_shdr->sh_entsize;
+  const char *hash_name;
+  const char *gnu_hash_name;
+  hash_name  = elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name);
+  gnu_hash_name  = elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name);
+
+  if (gnu_hash_data->d_size < 4 * sizeof (Elf32_Word))
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
+
+  uint32_t nentries = sym_shdr->sh_size / sym_shdr->sh_entsize;
   char *used = alloca (nentries);
   memset (used, '\0', nentries);
 
   /* First go over the GNU_HASH table and mark the entries as used.  */
   const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf;
   Elf32_Word gnu_nbucket = gnu_hasharr[0];
+  Elf32_Word gnu_symbias = gnu_hasharr[1];
   const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2;
   const Elf32_Word *gnu_bucket = (gnu_hasharr
 				  + (4 + gnu_hasharr[2] * bitmap_factor));
-  const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0] - gnu_hasharr[1];
+  const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0];
+
+  if (gnu_hasharr[2] == 0)
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' has zero bit mask words\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
+
+  uint64_t used_buf = ((4ULL + gnu_hasharr[2] * bitmap_factor + gnu_nbucket)
+		       * sizeof (Elf32_Word));
+  uint32_t max_nsyms = (gnu_hash_data->d_size - used_buf) / sizeof (Elf32_Word);
+  if (used_buf > gnu_hash_data->d_size)
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
 
   for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt)
     {
-      Elf32_Word symidx = gnu_bucket[cnt];
+      Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias;;
       if (symidx != STN_UNDEF)
 	do
-	  used[symidx] |= 1;
+	  {
+	    if (symidx >= max_nsyms || symidx >= nentries)
+	      {
+		ERROR (gettext ("\
+hash section [%2zu] '%s' invalid symbol index\n"),
+		       gnu_hash_idx, gnu_hash_name);
+		return;
+	      }
+	    used[symidx] |= 1;
+	  }
 	while ((gnu_chain[symidx++] & 1u) == 0);
     }
 
@@ -2342,37 +2418,82 @@ sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
   if (hash_shdr->sh_entsize == sizeof (Elf32_Word))
     {
       const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf;
+      if (hash_data->d_size < 2 * sizeof (Elf32_Word))
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
       Elf32_Word nbucket = hasharr[0];
+      Elf32_Word nchain = hasharr[1];
+      uint64_t hash_used = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
+      if (hash_used > hash_data->d_size)
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
       const Elf32_Word *bucket = &hasharr[2];
       const Elf32_Word *chain = &hasharr[2 + nbucket];
 
       for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
 	{
 	  Elf32_Word symidx = bucket[cnt];
-	  while (symidx != STN_UNDEF)
+	  while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
 	    {
 	      used[symidx] |= 2;
 	      symidx = chain[symidx];
 	    }
 	}
     }
-  else
+  else if (hash_shdr->sh_entsize == sizeof (Elf64_Word))
     {
       const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf;
+      if (hash_data->d_size < 2 * sizeof (Elf32_Word))
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
       Elf64_Xword nbucket = hasharr[0];
+      Elf64_Xword nchain = hasharr[1];
+      uint64_t maxwords = hash_data->d_size / sizeof (Elf64_Xword);
+      if (maxwords < 2
+	  || maxwords - 2 < nbucket
+	  || maxwords - 2 - nbucket < nchain)
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
       const Elf64_Xword *bucket = &hasharr[2];
       const Elf64_Xword *chain = &hasharr[2 + nbucket];
 
       for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
 	{
 	  Elf64_Xword symidx = bucket[cnt];
-	  while (symidx != STN_UNDEF)
+	  while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
 	    {
 	      used[symidx] |= 2;
 	      symidx = chain[symidx];
 	    }
 	}
     }
+  else
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' invalid sh_entsize\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
 
   /* Now see which entries are not set in one or both hash tables
      (unless the symbol is undefined in which case it can be omitted
@@ -2385,7 +2506,7 @@ sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
     ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
 	   hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
 
-  for (int cnt = 1; cnt < nentries; ++cnt)
+  for (uint32_t cnt = 1; cnt < nentries; ++cnt)
     if (used[cnt] != 0 && used[cnt] != 3)
       {
 	if (used[cnt] == 1)
@@ -2474,6 +2595,10 @@ section [%2d] '%s': invalid symbol index in sh_info\n"),
 	ERROR (gettext ("\
 section [%2d] '%s': cannot get symbol for signature\n"),
 	       idx, section_name (ebl, idx));
+      else if (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name) == NULL)
+	ERROR (gettext ("\
+section [%2d] '%s': cannot get symbol name for signature\n"),
+	       idx, section_name (ebl, idx));
       else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name),
 		       "") == 0)
 	ERROR (gettext ("\
@@ -2487,7 +2612,7 @@ section [%2d] '%s': signature symbol cannot be empty string\n"),
     }
 
   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
-  if (data == NULL)
+  if (data == NULL || data->d_buf == NULL)
     ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"),
 	   idx, section_name (ebl, idx), elf_errmsg (-1));
   else
@@ -2563,7 +2688,7 @@ section [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP
 			   val, section_name (ebl, val));
 		}
 
-	      if (++scnref[val] == 2)
+	      if (val < shnum && ++scnref[val] == 2)
 		ERROR (gettext ("\
 section [%2d] '%s' is contained in more than one section group\n"),
 		       val, section_name (ebl, val));
@@ -2648,7 +2773,7 @@ has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
     return 0;
 
   Elf_Data *data = elf_getdata (scn, NULL);
-  if (data == NULL)
+  if (data == NULL || shdr->sh_entsize == 0)
     return 0;
 
   if (shdr->sh_type == SHT_REL)
@@ -2762,7 +2887,7 @@ section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic s
 
   /* The number of elements in the version symbol table must be the
      same as the number of symbols.  */
-  if (shdr->sh_entsize && symshdr->sh_entsize
+  if (shdr->sh_entsize != 0 && symshdr->sh_entsize != 0
       && (shdr->sh_size / shdr->sh_entsize
 	  != symshdr->sh_size / symshdr->sh_entsize))
     ERROR (gettext ("\
@@ -2771,7 +2896,7 @@ section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\
 	   shdr->sh_link, section_name (ebl, shdr->sh_link));
 
   Elf_Data *symdata = elf_getdata (symscn, NULL);
-  if (symdata == NULL)
+  if (symdata == NULL || shdr->sh_entsize == 0)
     /* The error has already been reported.  */
     return;
 
@@ -2862,7 +2987,8 @@ unknown_dependency_p (Elf *elf, const char *fname)
   GElf_Shdr shdr_mem;
   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   Elf_Data *data = elf_getdata (scn, NULL);
-  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
+  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC
+      && data != NULL && shdr->sh_entsize != 0)
     for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
       {
 	GElf_Dyn dyn_mem;
@@ -2958,9 +3084,12 @@ section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
 	  const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
 					   aux->vna_name);
 	  if (verstr == NULL)
-	    ERROR (gettext ("\
+	    {
+	      ERROR (gettext ("\
 section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
-		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+		     idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+	      break;
+	    }
 	  else
 	    {
 	      GElf_Word hashval = elf_hash (verstr);
@@ -2974,7 +3103,6 @@ section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, ex
 				     ver_need);
 	      if (unlikely (res !=0))
 		{
-		  assert (res > 0);
 		  ERROR (gettext ("\
 section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
 			 idx, section_name (ebl, idx), need->vn_cnt - cnt2,
@@ -3002,9 +3130,12 @@ section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
 
       if ((need->vn_next != 0 || cnt > 0)
 	  && offset < auxoffset)
-	ERROR (gettext ("\
+	{
+	  ERROR (gettext ("\
 section [%2d] '%s': entry %d has invalid offset to next entry\n"),
-	       idx, section_name (ebl, idx), cnt);
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
     }
 }
 
@@ -3109,7 +3240,6 @@ section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
       int res = add_version (NULL, name, def->vd_ndx, ver_def);
       if (unlikely (res !=0))
 	{
-	  assert (res > 0);
 	  ERROR (gettext ("\
 section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
 		 idx, section_name (ebl, idx), cnt, name);
@@ -3129,9 +3259,12 @@ section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
 
 	  name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
 	  if (name == NULL)
-	    ERROR (gettext ("\
+	    {
+	      ERROR (gettext ("\
 section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
-		   idx, section_name (ebl, idx), cnt);
+		     idx, section_name (ebl, idx), cnt);
+	      break;
+	    }
 	  else
 	    {
 	      newname = alloca (sizeof (*newname));
@@ -3160,9 +3293,12 @@ section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
 
       if ((def->vd_next != 0 || cnt > 0)
 	  && offset < auxoffset)
-	ERROR (gettext ("\
+	{
+	  ERROR (gettext ("\
 section [%2d] '%s': entry %d has invalid offset to next entry\n"),
-	       idx, section_name (ebl, idx), cnt);
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
     }
 
   if (!has_base)
@@ -3201,7 +3337,7 @@ check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
     }
 
   Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL);
-  if (data == NULL || data->d_size == 0)
+  if (data == NULL || data->d_size == 0 || data->d_buf == NULL)
     {
       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
 	     idx, section_name (ebl, idx));
@@ -4084,7 +4220,7 @@ phdr[%d]: no note entries defined for the type of file\n"),
   Elf_Data *data = elf_getdata_rawchunk (ebl->elf,
 					 phdr->p_offset, phdr->p_filesz,
 					 ELF_T_NHDR);
-  if (data != NULL)
+  if (data != NULL && data->d_buf != NULL)
     notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset);
 
   if (notes_size == 0)
@@ -4103,7 +4239,7 @@ check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
     return;
 
   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
-  if (data == NULL)
+  if (data == NULL || data->d_buf == NULL)
     {
       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
 	     idx, section_name (ebl, idx));
@@ -4296,6 +4432,7 @@ program header offset in ELF header and PHDR entry do not match"));
 	      if (shdr != NULL
 		  && shdr->sh_type == (is_debuginfo
 				       ? SHT_NOBITS : SHT_PROGBITS)
+		  && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
 		  && ! strcmp (".eh_frame_hdr",
 			       elf_strptr (ebl->elf, shstrndx, shdr->sh_name)))
 		{
-- 
2.1.0



More information about the elfutils-devel mailing list