diff options
-rw-r--r-- | binutils/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/readelf.c | 23 |
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)); |