asan: Buffer overflow in evax_bfd_print_dst
authorAlan Modra <amodra@gmail.com>
Thu, 17 Mar 2022 07:25:48 +0000 (17:55 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 17 Mar 2022 11:02:44 +0000 (21:32 +1030)
With "name" a char*, the length at name[0] might be negative, escaping
buffer limit checks.

* vms-alpha.c (evax_bfd_print_dst): Make name an unsigned char*.
(evax_bfd_print_emh): Likewise.

bfd/vms-alpha.c

index 06fa891ac7018fb678a70ce19b9151f336d63a0e..4a92574c85055cacb726c893b42edf4b955e7ce8 100644 (file)
@@ -5939,9 +5939,9 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
     case EMH__C_MHD:
       {
        struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec;
-       const char * name;
-       const char * nextname;
-       const char * maxname;
+       unsigned char *name;
+       unsigned char *nextname;
+       unsigned char *maxname;
 
        /* PR 21840: Check for invalid lengths.  */
        if (rec_len < sizeof (* mhd))
@@ -5953,8 +5953,8 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
        fprintf (file, _("   structure level: %u\n"), mhd->strlvl);
        fprintf (file, _("   max record size: %u\n"),
                 (unsigned) bfd_getl32 (mhd->recsiz));
-       name = (char *)(mhd + 1);
-       maxname = (char *) rec + rec_len;
+       name = (unsigned char *) (mhd + 1);
+       maxname = (unsigned char *) rec + rec_len;
        if (name > maxname - 2)
          {
            fprintf (file, _("   Error: The module name is missing\n"));
@@ -7397,7 +7397,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
        case DST__K_MODBEG:
          {
            struct vms_dst_modbeg *dst = (void *)buf;
-           const char *name = (const char *)buf + sizeof (*dst);
+           unsigned char *name = buf + sizeof (*dst);
 
            fprintf (file, _("modbeg\n"));
            if (len < sizeof (*dst))
@@ -7421,7 +7421,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
                    name += name[0] + 1;
                    nlen = len - 1;
                    fprintf (file, _("   compiler   : %.*s\n"),
-                            name[0] > nlen ? nlen: name[0], name + 1);
+                            name[0] > nlen ? nlen : name[0], name + 1);
                  }
              }
          }
@@ -7432,7 +7432,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
        case DST__K_RTNBEG:
          {
            struct vms_dst_rtnbeg *dst = (void *)buf;
-           const char *name = (const char *)buf + sizeof (*dst);
+           unsigned char *name = buf + sizeof (*dst);
 
            fputs (_("rtnbeg\n"), file);
            if (len >= sizeof (*dst))
@@ -7485,7 +7485,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
        case DST__K_BLKBEG:
          {
            struct vms_dst_blkbeg *dst = (void *)buf;
-           const char *name = (const char *)buf + sizeof (*dst);
+           unsigned char *name = buf + sizeof (*dst);
 
            if (len > sizeof (*dst))
              {
@@ -7536,7 +7536,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
        case DST__K_RECBEG:
          {
            struct vms_dst_recbeg *recbeg = (void *)buf;
-           const char *name = (const char *)buf + sizeof (*recbeg);
+           unsigned char *name = buf + sizeof (*recbeg);
 
            if (len > sizeof (*recbeg))
              {
@@ -7750,7 +7750,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
                  case DST__K_SRC_DECLFILE:
                    {
                      struct vms_dst_src_decl_src *src = (void *) buf;
-                     const char *name;
+                     unsigned char *name;
                      int nlen;
 
                      if (len < sizeof (*src))
@@ -7772,7 +7772,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
                      if (src->length > len || src->length <= sizeof (*src))
                        break;
                      nlen = src->length - sizeof (*src) - 1;
-                     name = (const char *) buf + sizeof (*src);
+                     name = buf + sizeof (*src);
                      fprintf (file, _("   filename   : %.*s\n"),
                               name[0] > nlen ? nlen : name[0], name + 1);
                      if (name[0] >= nlen)