From 62e6979095ab19728ca3f2f86f98e8edb8f33cc8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 8 Sep 2025 08:37:13 +0930 Subject: 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. --- bfd/vms-alpha.c | 57 ++++++++++++++++++++++++++++----------------------------- 1 file 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: -- cgit v1.1