bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

XCOFF Memory Overwrite in coff-rs6000.c


From: Michael Walsh
Subject: XCOFF Memory Overwrite in coff-rs6000.c
Date: Mon, 24 Feb 2003 14:06:06 -0500

Hello,

AIX 4.3 extends the x_file.x_n field of an auxiliary entry for C_FILE symbols and there is a memory overwrite that shows up when an XCOFF object file that makes use of these fields
is linked with ld. Apple's pre MacOS X XCOFF format uses the extra fields.

Discussion:
C_FILE storage class can have up to 4 auxiliary (XCOFF) entries and two additonal fields are defined in the union x_file.x_n (x_pad/x_ftype). The x_ftype is the type of each aux entry
and macros are defined for them (see below).
The gcc compiler and assembler make no use of the extra entries and what I have done below should not have any affect on gas (unless support is added). Since, the extra aux entries are not used by gas, all that has to be done, is to make sure the ld/ar copy the aux entries and set the x_ftype field correctly. Objdump doesn't display aux entries for C_FILE it just writes out the word File for each entry, so nothing has to be done unless someone wishes
to add support.

Commented code represents changes (additions/modifictaions/bug description) all other comments have been removed. I realize there are other ways to do this, but I think it is worth it to
add the fields and macros.

Sincerely,
Michael J. Walsh

/* 3 headers and one source file would require  modifications */

Stack trace for ld:
main
ldwrite
_bfd_xcoff_bfd_final_link
xcoff_link_input_bfd
_bfd_xcoff_swap_aux_in
/***************************** /src/bfd/coff-rs6000.c ********************/
void
_bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
     bfd *abfd;
     PTR ext1;
     int type;
     int class;
     int indx;
     int numaux;
     PTR in1;
{
  AUXENT * ext = (AUXENT *)ext1;
  union internal_auxent *in = (union internal_auxent *)in1;

  switch (class)
    {
    case C_FILE:
      if (ext->x_file.x_fname[0] == 0)
        {
          in->x_file.x_n.x_zeroes = 0;
          in->x_file.x_n.x_offset =
            H_GET_32 (abfd, ext->x_file.x_n.x_offset);
#ifdef USE_XCOFF_FTYPE /* for now, defined on the command line at build time -- add mjw */
          in->x_file.x_n.x_ftype =
                H_GET_8 (abfd, ext->x_file.x_n.x_ftype); /* add mjw mpw */
#endif
        }
      else
        {
/* The code below will cause a memory overwrite that will sometimes crash ld. The aux entry passed, `in1' is a single entry. There is also no need to copy multiple entries because in the function:
         xcoff_link_input_bfd at line 4743 (approximation)
                  for (i = 0; i < isymp->n_numaux && esym < esym_end; i++)
            {
              union internal_auxent aux;

              bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type,
                                    isymp->n_sclass, i, isymp->n_numaux,
                                    (PTR) &aux);
                ...
                ...
            }
is looping through the aux entries one at at time. All that needs to be done is
   to copy x_fname and the byte for x_ftype */
#if 0 /*  memory overwrite */
          if (numaux > 1)
            {
              if (indx == 0)
                memcpy (in->x_file.x_fname, ext->x_file.x_fname,
                        numaux * sizeof (AUXENT)); /* ?? */
            }
          else
            {
              memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
            }
#else
              memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
#ifdef USE_XCOFF_FTYPE /* for now, defined on the command line at build time -- add mjw */
              in->x_file.x_n.x_ftype = H_GET_8 (abfd, ext->x_file.x_n.x_ftype);
#endif  /*  add  mjw  */
#endif /*  add  mjw  */
        }
      goto end;

/* ... */
/* ... */
/* ... */

}

/************************** /src/bfd/coff-rs6000.c *******************************************/
unsigned int
_bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
     bfd * abfd;
     PTR   inp;
     int   type;
     int   class;
     int   indx ATTRIBUTE_UNUSED;
     int   numaux ATTRIBUTE_UNUSED;
     PTR   extp;
{
  union internal_auxent *in = (union internal_auxent *)inp;
  AUXENT *ext = (AUXENT *)extp;

  memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
  switch (class)
    {
    case C_FILE:
      if (in->x_file.x_fname[0] == 0)
        {
          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
          H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
#ifdef USE_XCOFF_FTYPE /* for now, defined on the command line at build time -- add mjw */ H_PUT_8 (abfd,in->x_file.x_n.x_ftype, ext->x_file.x_n.x_ftype);/* add mjw */
#endif
        }
      else
#ifdef USE_XCOFF_FTYPE /* for now, defined on the command line at build time -- add mjw */
        { /* add mjw */
memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); /* add mjw */ H_PUT_8 (abfd,in->x_file.x_n.x_ftype, ext->x_file.x_n.x_ftype); /* add mjw */
        } /* add mjw */
#else
    memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
#endif /* add mjw */
      goto end;

/* ... */
/* ... */
/* ... */

}

/******************** FILE /src/include/coff/xcoff.h ******************/
/* added  definitions to xcoff.h */
/* File string types -- x_ftype  */
#define XFT_FN   0 /* source file name */
#define XFT_CT   1 /* compile time stamp */
#define XFT_CV   2 /* compiler version number */
#define XFT_CD 128 /* compiler defined information */



/***************** FILE /src/include/coff/rs6000.h **********************/
union external_auxent {
        struct {
                char x_tagndx[4];
                union {
                        struct {
                            char  x_lnno[2];
                            char  x_size[2];
                        } x_lnsz;
                        char x_fsize[4];
                } x_misc;
                union {
                        struct {
                            char x_lnnoptr[4];
                            char x_endndx[4];
                        } x_fcn;
                        struct {
                            char x_dimen[E_DIMNUM][2];
                        } x_ary;
                } x_fcnary;
                char x_tvndx[2];
        } x_sym;

        union {
                char x_fname[E_FILNMLEN];
                struct {
                        char x_zeroes[4];
                        char x_offset[4];
#ifdef USE_XCOFF_FTYPE /* for now defined on the command line at build time -- add mjw */
                        char x_pad[E_FILNMLEN-8];   /* add  mjw  */
unsigned char x_ftype[1]; /* file string type -- add mjw */
#endif /* add  mjw  */
                } x_n;
        } x_file;


/* ... */
/* ... */
/* ... */
};

/***************** FILE /src/include/coff/internal.h **********************/

union internal_auxent
{
  struct
  {

    union
    {
      long l;
      struct coff_ptr_struct *p;
    }     x_tagndx;

    union
    {
      struct
      {
        unsigned short x_lnno;
        unsigned short x_size;
      }      x_lnsz;
      long x_fsize;
    }     x_misc;

    union
    {
      struct
      {
        bfd_signed_vma x_lnnoptr;
        union
        {
          long l;
          struct coff_ptr_struct *p;
        }     x_endndx;
      }      x_fcn;

      struct
      {
        unsigned short x_dimen[DIMNUM];
      }      x_ary;
    }     x_fcnary;

    unsigned short x_tvndx;
  }      x_sym;

  union
  {
    char x_fname[FILNMLEN];
    struct
    {
      long x_zeroes;
      long x_offset;
#ifdef USE_XCOFF_FTYPE /* for now, defined on the command line at build time -- add mjw */
      char x_pad[FILNMLEN-8]; /* add mjw  */
      unsigned char x_ftype;/* file string type --add mjw */
#endif
    }      x_n;
  }     x_file;

/* ... */
/* ... */
/* ... */
};




reply via email to

[Prev in Thread] Current Thread [Next in Thread]