asan: Buffer overflow in evax_bfd_print_dst
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.
This commit is contained in:
+12
-12
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user