[PATCH] elflint: Correct gnu_symbias usage in compare_hash_gnu_hash.

Mark Wielaard mjw at redhat.com
Mon Mar 9 15:45:20 UTC 2015


commit 0a545e "elflint: Add various low-level checks." introduced a bug
in the handling of the gnu_symbias. The symbol in the bucket should first
be compared to STN_UNDEF before applying the bias. And the used symbol
index should have the bias added when compared against plain hash symbol.

Found on Debian wheezy with run-elflint-self.sh.

Signed-off-by: Mark Wielaard <mjw at redhat.com>
---
 src/ChangeLog |  4 ++++
 src/elflint.c | 30 ++++++++++++++++--------------
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index dad984e..bb9580a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-09  Mark Wielaard  <mjw at redhat.com>
+
+	* elflint.c (compare_hash_gnu_hash): Correct gnu_symbias usage.
+
 2015-01-03  Mark Wielaard  <mjw at redhat.com>
 
 	* elfcmp (main): Check section name is not NULL. Check sh_entsize
diff --git a/src/elflint.c b/src/elflint.c
index 143424c..a6f9b68 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -2397,20 +2397,22 @@ hash section [%2zu] '%s' uses too much data\n"),
 
   for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt)
     {
-      Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias;;
-      if (symidx != STN_UNDEF)
-	do
-	  {
-	    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);
+      if (gnu_bucket[cnt] != STN_UNDEF)
+	{
+	  Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias;
+	  do
+	    {
+	      if (symidx >= max_nsyms || symidx + gnu_symbias >= nentries)
+		{
+		  ERROR (gettext ("\
+hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ", nentries: %" PRIu32 "\n"),
+			 gnu_hash_idx, gnu_hash_name, symidx, max_nsyms, nentries);
+		  return;
+		}
+	      used[symidx + gnu_symbias] |= 1;
+	    }
+	  while ((gnu_chain[symidx++] & 1u) == 0);
+	}
     }
 
   /* Now go over the old hash table and check that we cover the same
-- 
1.8.3.1



More information about the elfutils-devel mailing list