bug-binutils
[Top][All Lists]
Advanced

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

[Bug binutils/21440] New: Malicious PE with invalid extended relocation


From: jgj212 at gmail dot com
Subject: [Bug binutils/21440] New: Malicious PE with invalid extended relocation can cause binutils/objdumo 2.28 to allocate any-size big memory
Date: Thu, 27 Apr 2017 06:10:21 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=21440

            Bug ID: 21440
           Summary: Malicious PE with invalid extended relocation can
                    cause binutils/objdumo 2.28 to allocate any-size big
                    memory
           Product: binutils
           Version: 2.28
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: jgj212 at gmail dot com
  Target Milestone: ---

Created attachment 10029
  --> https://sourceware.org/bugzilla/attachment.cgi?id=10029&action=edit
Malicious PE with invalid extended relocation sample

-----------------------
$objdump -x $FILE
-----------------------

With x option, objdump will allocate memory to store relocation data, this is
done in the following function:
static void
dump_relocs_in_section (bfd *abfd,
                        asection *section,
                        void *dummy ATTRIBUTE_UNUSED)
{
        ….
        relsize = bfd_get_reloc_upper_bound (abfd, section); //can be
controlled
        …
        relpp = (arelent **) xmalloc (relsize);  //allocate memory
        relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);  //read
reloc data
        …
}

the relsize is computed as :
(asect->reloc_count + 1) * sizeof (arelent *)    //
coff_get_reloc_upper_bound(…)

In the coff standard, reoc_count is WORD, which is 16bit wide. sizeof (arelent
*) is constant and small. So normally, the result is small. But when PE section
contain extended relocation, everything will go bad. 

PE section header is inited in the following function:
static void
coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
                         asection * section,
                         void * scnhdr)
{
        …
        /* Check for extended relocs.  */
        if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
        {
struct external_reloc dst;
      struct internal_reloc n;
      file_ptr oldpos = bfd_tell (abfd);
      bfd_size_type relsz = bfd_coff_relsz (abfd);

      if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0) //seek to the
first reloc data
         return;

      if (bfd_bread (& dst, relsz, abfd) != relsz) //read the first reloc data
          return; 

      coff_swap_reloc_in (abfd, &dst, &n);//fill struct
      if (bfd_seek (abfd, oldpos, 0) != 0)
                return;

      section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;  //can be
controlled
      section->rel_filepos += relsz;
}
…
}       

>From the above, when pe section contain extended relocation, reloc_count is
assigned from n.r_vaddr.  n is a instance of struct internal_reloc as follow:
struct internal_reloc
{
  bfd_vma r_vaddr;              /* Virtual address of reference */
  long r_symndx;                /* Index into symbol table      */
  unsigned short r_type;        /* Relocation type              */
  unsigned char r_size;         /* Used by RS/6000 and ECOFF    */
  unsigned char r_extern;       /* Used by ECOFF                */
  unsigned long r_offset;       /* Used by Alpha ECOFF, SPARC, others */
};

r_vaddr's type is unsigned long, it can be 32bit and 64bit, according to the
os-archive. it is from the dst, which is a instance of struct external_reloc as
follow:
struct external_reloc
{
  char r_vaddr[4];
  char r_symndx[4];
  char r_type[2];
};

So n.r_vaddr is really 32bit wide,  section->reloc_count is also 32bit wide.
(asect->reloc_count + 1) * sizeof (arelent *) can be very large.


To control the memory size, it just need to modify the r_vaddr field of first
reloc data, if can be from 0 to 0Xffffffff.  

This could cause memory exhaustion to dos.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

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