aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-04-26 18:30:50 +0930
committerAlan Modra <amodra@gmail.com>2020-04-26 23:50:18 +0930
commit90837ea7211e7911ca6c729c2dd697b35a1054ad (patch)
treedbdaa80baf63732886a2bb797f741942fad09912
parentbc3609fd3891c1cc0007eccd74bca98aabc03996 (diff)
downloadgdb-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/ChangeLog7
-rw-r--r--binutils/readelf.c39
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);