aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-09-08 08:37:13 +0930
committerAlan Modra <amodra@gmail.com>2025-09-08 22:17:46 +0930
commit62e6979095ab19728ca3f2f86f98e8edb8f33cc8 (patch)
tree18ed86f4e0d09b692d21f538693434448ec8eef7
parenta2298f23f2e23ff6f191e36540208a90fffd317b (diff)
downloadbinutils-62e6979095ab19728ca3f2f86f98e8edb8f33cc8.zip
binutils-62e6979095ab19728ca3f2f86f98e8edb8f33cc8.tar.gz
binutils-62e6979095ab19728ca3f2f86f98e8edb8f33cc8.tar.bz2
vms-alpha: ehdr checks
I noticed that _bfd_vms_slurp_ehdr wrongly used buf_size (rather than rec_size) when sanity checking. * vms-alpha.c (_bfd_vms_slurp_ehdr): Don't allow access to uninitialised buffer memory. Tidy code generally, using remaining record length for sanity checks.
-rw-r--r--bfd/vms-alpha.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index 80a559d..f8eaf6f 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -892,65 +892,64 @@ static bool
_bfd_vms_slurp_ehdr (bfd *abfd)
{
unsigned char *ptr;
- unsigned char *vms_rec;
- unsigned char *end;
+ unsigned int len, slen;
int subtype;
- vms_rec = PRIV (recrd.rec);
- /* PR 17512: file: 62736583. */
- end = PRIV (recrd.buf) + PRIV (recrd.buf_size);
-
vms_debug2 ((2, "HDR/EMH\n"));
- subtype = bfd_getl16 (vms_rec + 4);
+ ptr = PRIV (recrd.rec);
+ len = PRIV (recrd.rec_size);
+ if (len < 6)
+ goto fail;
+
+ subtype = bfd_getl16 (ptr + 4);
vms_debug2 ((3, "subtype %d\n", subtype));
+ ptr += 6;
+ len -= 6;
switch (subtype)
{
case EMH__C_MHD:
/* Module header. */
- if (vms_rec + 21 >= end)
- goto fail;
- PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
- PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
- PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
- PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
- if ((vms_rec + 20 + vms_rec[20] + 1) >= end)
+ if (len < 15)
goto fail;
+ PRIV (hdr_data).hdr_b_strlvl = *ptr;
+ PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (ptr + 2);
+ PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (ptr + 6);
+ PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (ptr + 10);
+ ptr += 14;
+ len -= 14;
PRIV (hdr_data).hdr_t_name
- = _bfd_vms_save_counted_string (abfd, vms_rec + 20, vms_rec[20]);
- ptr = vms_rec + 20 + vms_rec[20] + 1;
- if ((ptr + *ptr + 1) >= end)
+ = _bfd_vms_save_counted_string (abfd, ptr, len);
+ slen = *ptr + 1;
+ if (len <= slen)
goto fail;
+ ptr += slen;
+ len -= slen;
PRIV (hdr_data).hdr_t_version
- = _bfd_vms_save_counted_string (abfd, ptr, *ptr);
- ptr += *ptr + 1;
- if (ptr + 17 >= end)
+ = _bfd_vms_save_counted_string (abfd, ptr, len);
+ slen = *ptr + 1;
+ if (len < slen + 17)
goto fail;
+ ptr += slen;
PRIV (hdr_data).hdr_t_date
= _bfd_vms_save_sized_string (abfd, ptr, 17);
break;
case EMH__C_LNM:
- if (vms_rec + PRIV (recrd.rec_size - 6) > end)
- goto fail;
PRIV (hdr_data).hdr_c_lnm
- = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
+ = _bfd_vms_save_sized_string (abfd, ptr, len);
break;
case EMH__C_SRC:
- if (vms_rec + PRIV (recrd.rec_size - 6) > end)
- goto fail;
PRIV (hdr_data).hdr_c_src
- = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
+ = _bfd_vms_save_sized_string (abfd, ptr, len);
break;
case EMH__C_TTL:
- if (vms_rec + PRIV (recrd.rec_size - 6) > end)
- goto fail;
PRIV (hdr_data).hdr_c_ttl
- = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
+ = _bfd_vms_save_sized_string (abfd, ptr, len);
break;
case EMH__C_CPR: