Re: vms buffer overflows and large memory allocation
authorAlan Modra <amodra@gmail.com>
Mon, 24 Feb 2020 02:49:13 +0000 (13:19 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 24 Feb 2020 02:51:48 +0000 (13:21 +1030)
The last patch wasn't quite correct.  I'd missed the fact that sbm_off
had been updated.

* vms-lib.c (_bfd_vms_lib_archive_p): Correct overflow checks.

bfd/ChangeLog
bfd/vms-lib.c

index 58b560d1aaca3f2942585b966537c5f1740ea37c..eeb042c32f39b08e0b0f6a4905e96e7364b0b412 100644 (file)
@@ -1,3 +1,7 @@
+2020-02-24  Alan Modra  <amodra@gmail.com>
+
+       * vms-lib.c (_bfd_vms_lib_archive_p): Correct overflow checks.
+
 2020-02-24  Alan Modra  <amodra@gmail.com>
 
        * vms-lib.c (struct carsym_mem): Add limit.
index 3b42857aa9ce7e89d1e5c66da7c1a2e55eb24f42..87f865864c644ce55a317bf63bc7283f83242b50 100644 (file)
@@ -627,6 +627,8 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
          sbm = (struct vms_dcxsbm *) (buf + sbm_off);
          sbm_sz = bfd_getl16 (sbm->size);
          sbm_off += sbm_sz;
+         if (sbm_off > reclen)
+           goto err;
 
          sbmdesc->min_char = sbm->min_char;
          BFD_ASSERT (sbmdesc->min_char == 0);
@@ -639,21 +641,21 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
            goto err;
          sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
          off = bfd_getl16 (sbm->flags);
-         if (off > reclen - sbm_off
-             || reclen - sbm_off - off < l)
+         if (off > sbm_sz
+             || sbm_sz - off < l)
            goto err;
          memcpy (sbmdesc->flags, (bfd_byte *) sbm + off, l);
          sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
          off = bfd_getl16 (sbm->nodes);
-         if (off > reclen - sbm_off
-             || reclen - sbm_off - off < 2 * sbm_len)
+         if (off > sbm_sz
+             || sbm_sz - off < 2 * sbm_len)
            goto err;
          memcpy (sbmdesc->nodes, (bfd_byte *) sbm + off, 2 * sbm_len);
          off = bfd_getl16 (sbm->next);
          if (off != 0)
            {
-             if (off > reclen - sbm_off
-                 || reclen - sbm_off - off < 2 * sbm_len)
+             if (off > sbm_sz
+                 || sbm_sz - off < 2 * sbm_len)
                goto err;
              /* Read the 'next' array.  */
              sbmdesc->next = (unsigned short *) bfd_alloc (abfd, 2 * sbm_len);