From 80053e466b3a8055334b9be9bac7d99e0d617cbe Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 19 Jun 2017 13:01:57 +0100 Subject: [PATCH] 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. --- bfd/ChangeLog | 8 +++++++- bfd/vms-alpha.c | 27 +++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a900e1ac165..6aa4c9099f7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,12 @@ 2017-06-19 Nick Clifton - 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 + + 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 be5c06f648f..73f6976325f 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", -- 2.30.2