aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-02-24 01:47:51 -0500
committerMike Frysinger <vapier@gentoo.org>2015-02-24 10:36:51 -0500
commit94d15024fe3dff908ab570aaa741b1c834c856d6 (patch)
tree06538d9c122471238ba178b4b9babd4adbf9be12 /binutils/readelf.c
parent884151a7b8f1770a823e5017c8f5025802c44f24 (diff)
downloadgdb-94d15024fe3dff908ab570aaa741b1c834c856d6.zip
gdb-94d15024fe3dff908ab570aaa741b1c834c856d6.tar.gz
gdb-94d15024fe3dff908ab570aaa741b1c834c856d6.tar.bz2
readelf: handle corrupted chains better
The current chain walker tries to protect itself against loops, by only works with loops of length 1: a chain that points to itself. If you have a chain longer than that (3->4->3->4->...), readelf will still hang. Since we know the max length of the chain, simply abort when we've walked more times than that. The only way that could have happened is if there was a loop.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c23
1 files changed, 13 insertions, 10 deletions
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));