diff options
author | Alan Modra <amodra@gmail.com> | 2020-04-26 18:30:50 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-04-26 23:50:18 +0930 |
commit | 90837ea7211e7911ca6c729c2dd697b35a1054ad (patch) | |
tree | dbdaa80baf63732886a2bb797f741942fad09912 | |
parent | bc3609fd3891c1cc0007eccd74bca98aabc03996 (diff) | |
download | gdb-90837ea7211e7911ca6c729c2dd697b35a1054ad.zip gdb-90837ea7211e7911ca6c729c2dd697b35a1054ad.tar.gz gdb-90837ea7211e7911ca6c729c2dd697b35a1054ad.tar.bz2 |
readelf: NULL dereference
This fixes another missing error check.
* readelf.c (get_num_dynamic_syms): Check DT_MIPS_XHASH was
read before dereferencing, and gracefully return. Remove
gnu_hash_error variable. Free gnu hash arrays if number of
syms found is zero.
-rw-r--r-- | binutils/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/readelf.c | 39 |
2 files changed, 16 insertions, 30 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index ad3846a..7fb2dbe 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2020-04-26 Alan Modra <amodra@gmail.com> + + * readelf.c (get_num_dynamic_syms): Check DT_MIPS_XHASH was + read before dereferencing, and gracefully return. Remove + gnu_hash_error variable. Free gnu hash arrays if number of + syms found is zero. + 2020-04-24 Alan Modra <amodra@gmail.com> * readelf.c (get_num_dynamic_syms): Check for nbuckets and nchains diff --git a/binutils/readelf.c b/binutils/readelf.c index 8e8ade8..68dfa32 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -10026,7 +10026,6 @@ get_num_dynamic_syms (Filedata * filedata) bfd_vma i, maxchain = 0xffffffff, bitmaskwords; bfd_vma buckets_vma; unsigned long hn; - bfd_boolean gnu_hash_error = FALSE; if (fseek (filedata->handle, (filedata->archive_file_offset @@ -10036,14 +10035,12 @@ get_num_dynamic_syms (Filedata * filedata) SEEK_SET)) { error (_("Unable to seek to start of dynamic information\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } if (fread (nb, 16, 1, filedata->handle) != 1) { error (_("Failed to read in number of buckets\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } @@ -10062,7 +10059,6 @@ get_num_dynamic_syms (Filedata * filedata) SEEK_SET)) { error (_("Unable to seek to start of dynamic information\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } @@ -10070,29 +10066,20 @@ get_num_dynamic_syms (Filedata * filedata) = get_dynamic_data (filedata, filedata->ngnubuckets, 4); if (filedata->gnubuckets == NULL) - { - gnu_hash_error = TRUE; - goto no_gnu_hash; - } + goto no_gnu_hash; for (i = 0; i < filedata->ngnubuckets; i++) if (filedata->gnubuckets[i] != 0) { if (filedata->gnubuckets[i] < filedata->gnusymidx) - { - gnu_hash_error = TRUE; - goto no_gnu_hash; - } + goto no_gnu_hash; if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain) maxchain = filedata->gnubuckets[i]; } if (maxchain == 0xffffffff) - { - gnu_hash_error = TRUE; - goto no_gnu_hash; - } + goto no_gnu_hash; maxchain -= filedata->gnusymidx; @@ -10105,7 +10092,6 @@ get_num_dynamic_syms (Filedata * filedata) SEEK_SET)) { error (_("Unable to seek to start of dynamic information\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } @@ -10114,15 +10100,11 @@ get_num_dynamic_syms (Filedata * filedata) if (fread (nb, 4, 1, filedata->handle) != 1) { error (_("Failed to determine last chain length\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } if (maxchain + 1 == 0) - { - gnu_hash_error = TRUE; - goto no_gnu_hash; - } + goto no_gnu_hash; ++maxchain; } @@ -10136,7 +10118,6 @@ get_num_dynamic_syms (Filedata * filedata) SEEK_SET)) { error (_("Unable to seek to start of dynamic information\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } @@ -10144,10 +10125,7 @@ get_num_dynamic_syms (Filedata * filedata) filedata->ngnuchains = maxchain; if (filedata->gnuchains == NULL) - { - gnu_hash_error = TRUE; - goto no_gnu_hash; - } + goto no_gnu_hash; if (filedata->dynamic_info_DT_MIPS_XHASH) { @@ -10159,11 +10137,12 @@ get_num_dynamic_syms (Filedata * filedata) SEEK_SET)) { error (_("Unable to seek to start of dynamic information\n")); - gnu_hash_error = TRUE; goto no_gnu_hash; } filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4); + if (filedata->mipsxlat == NULL) + goto no_gnu_hash; } for (hn = 0; hn < filedata->ngnubuckets; ++hn) @@ -10190,9 +10169,9 @@ get_num_dynamic_syms (Filedata * filedata) && (filedata->gnuchains[off++] & 1) == 0); } - no_gnu_hash: - if (gnu_hash_error) + if (num_of_syms == 0) { + no_gnu_hash: if (filedata->mipsxlat) { free (filedata->mipsxlat); |