diff options
author | Alan Modra <amodra@gmail.com> | 2025-09-08 08:37:13 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-09-08 22:17:46 +0930 |
commit | 62e6979095ab19728ca3f2f86f98e8edb8f33cc8 (patch) | |
tree | 18ed86f4e0d09b692d21f538693434448ec8eef7 | |
parent | a2298f23f2e23ff6f191e36540208a90fffd317b (diff) | |
download | binutils-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.c | 57 |
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: |