aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog7
-rw-r--r--binutils/readelf.c23
2 files changed, 20 insertions, 10 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index a462145..599c82c 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-24 Mike Frysinger <vapier@gentoo.org>
+
+ PR binutils/17531
+ * readelf.c (process_symbol_table): Declare chained. Increment it
+ in every loop. Abort when chained is larger than nchains. Move
+ error check outside of chain loop.
+
2015-02-24 Dmitry Antipov <dantipov@nvidia.com>
* readelf.c (find_symbol_for_address): Use a binary search to
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 7394e76..b3f4733 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -10783,6 +10783,7 @@ process_symbol_table (FILE * file)
unsigned long maxlength = 0;
unsigned long nzero_counts = 0;
unsigned long nsyms = 0;
+ unsigned long chained;
printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
(unsigned long) nbuckets);
@@ -10797,21 +10798,23 @@ process_symbol_table (FILE * file)
printf (_(" Length Number %% of total Coverage\n"));
for (hn = 0; hn < nbuckets; ++hn)
{
- for (si = buckets[hn]; si > 0 && si < nchains && si < nbuckets; si = chains[si])
+ for (si = buckets[hn], chained = 0;
+ si > 0 && si < nchains && si < nbuckets && chained <= nchains;
+ si = chains[si], ++chained)
{
++nsyms;
if (maxlength < ++lengths[hn])
++maxlength;
-
- /* PR binutils/17531: A corrupt binary could contain broken
- histogram data. Do not go into an infinite loop trying
- to process it. */
- if (chains[si] == si)
- {
- error (_("histogram chain links to itself\n"));
- break;
- }
}
+
+ /* PR binutils/17531: A corrupt binary could contain broken
+ histogram data. Do not go into an infinite loop trying
+ to process it. */
+ if (chained > nchains)
+ {
+ error (_("histogram chain is corrupt\n"));
+ break;
+ }
}
counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));