diff options
author | Nick Clifton <nickc@redhat.com> | 2017-06-19 13:01:57 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-06-19 13:01:57 +0100 |
commit | 80053e466b3a8055334b9be9bac7d99e0d617cbe (patch) | |
tree | 08f6c962fca058105b37806d90a399c81452a3a8 | |
parent | 16b7a7199881fa26fc863279bbf08741e5674b5d (diff) | |
download | gdb-80053e466b3a8055334b9be9bac7d99e0d617cbe.zip gdb-80053e466b3a8055334b9be9bac7d99e0d617cbe.tar.gz gdb-80053e466b3a8055334b9be9bac7d99e0d617cbe.tar.bz2 |
Fix access violation disassembling a corrupt VMS binary.
PR binutils/21611
* vms-alpha.c (_bfd_vms_slurp_eihs): Check for invalid offset
before reading the EIHS structure entries.
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/vms-alpha.c | 27 |
2 files changed, 28 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a900e1a..6aa4c90 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,12 @@ 2017-06-19 Nick Clifton <nickc@redhat.com> - PR 21615 + PR binutils/21611 + * vms-alpha.c (_bfd_vms_slurp_eihs): Check for invalid offset + before reading the EIHS structure entries. + +2017-06-19 Nick Clifton <nickc@redhat.com> + + PR binutils/21615 * vms-alpha.c (_bfd_vms_slurp_egsd): Use unsigned int for gsd_size. Check that there are enough bytes remaining to read the type and size of the next egsd. Check that the size of the egsd diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index be5c06f..73f6976 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -622,14 +622,29 @@ static bfd_boolean _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) { unsigned char *p = PRIV (recrd.rec) + offset; - unsigned int gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN); - unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS__L_GSTSIZE); - unsigned int dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN); - unsigned int dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE); - unsigned int dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN); - unsigned int dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES); + unsigned int gstvbn; + unsigned int gstsize ATTRIBUTE_UNUSED; + unsigned int dstvbn; + unsigned int dstsize; + unsigned int dmtvbn; + unsigned int dmtbytes; asection *section; + /* PR 21611: Check that offset is valid. */ + if (offset > PRIV (recrd.rec_size) - (EIHS__L_DMTBYTES + 4)) + { + _bfd_error_handler (_("Unable to read EIHS record at offset %#x"), offset); + bfd_set_error (bfd_error_file_truncated); + return FALSE; + } + + gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN); + gstsize = bfd_getl32 (p + EIHS__L_GSTSIZE); + dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN); + dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE); + dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN); + dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES); + #if VMS_DEBUG vms_debug (8, "_bfd_vms_slurp_ihs\n"); vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n", |