bug-binutils
[Top][All Lists]
Advanced

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

[Bug binutils/19296] New: memory crush(Out of bound read error)caused by


From: 0yangke0 at gmail dot com
Subject: [Bug binutils/19296] New: memory crush(Out of bound read error)caused by insufficient check for parsed_size in archive.c
Date: Thu, 26 Nov 2015 07:26:31 +0000

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

            Bug ID: 19296
           Summary: memory crush(Out of bound read error)caused by
                    insufficient check for parsed_size in archive.c
           Product: binutils
           Version: 2.23
            Status: NEW
          Severity: critical
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: 0yangke0 at gmail dot com
  Target Milestone: ---

Created attachment 8814
  --> https://sourceware.org/bugzilla/attachment.cgi?id=8814&action=edit
exploit input file for objdump and nm

Hi,
We find an memory crush bug of objdump and nm at least before binuitls-2.24,and 
This bug is caused by missing check of read variable "parsed_size" in
archive.c:481(The following description use binutils-2.23 as an example).
Also we find that this bug still exists in versions after binutils-2.23 by
reviewing the source code, but it doesn't crash in our test in Ubuntu 14.04 as
for the dynamic allocation area is all flushed by zero (00 00 00 00).

We create a trigger input file for this bug and we make it as an attachment.

object -t option and default option and nm default 
e.g #objdump -t exploit_file
    #objdump exploit_file
    #nm exploit_file


In line archive.c:481, parsed_size is assigned by the hdr.ar_size(in
function:_bfd_generic_read_ar_hdr_mag).

481:  scan = sscanf (hdr.ar_size, "%" BFD_VMA_FMT "u", &parsed_size);

Thus if we construct "30 00 00 00 00 00 00 00 00 00" for hdr.ar_size, then we
get a "0"string(30 is the ASCII number of zero),and the parsed_size will then
become zero. 
In line 562 the parse_size is assigned to ared->parsed_size:
562       ared->parsed_size = parsed_size;

The struct pointer ared is returned and assigned to mapdata in line 883 in
function _bfd_generic_read_ar_hdr:

883:     mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);

In line 886, mapdata->parsed_size is assigned to parsed_size(note that we are
in function _bfd_generic_read_ar_hdr now):

886:      parsed_size = mapdata->parsed_size;

In line 889, parsed_size is used as the length to apply for dynamic memory.

889:      raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);

As parsed_size is zero so pointer raw_armap is not NULL and points to some
padding bytes.  
It passed the following check as the parsed_size is zero now and the condition
is false.

893:      if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size)

In line 902, ardata->symdef_count is assigned by the former applied  dynamic
padding bytes.The expanded macro H_GET_32 will call bfd_getl32 to convert the
four bytes to integer.

902:      ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE;
903:
904:      if (ardata->symdef_count * BSD_SYMDEF_SIZE >
905:          parsed_size - BSD_SYMDEF_COUNT_SIZE)

BSD_SYMDEF_SIZE expanded to 8.
The following error check doesn't work as "parsed_size-BSD_SYMDEF_COUNT_SIZE"
will be a very large unsigned number 0xfffffffc.

The following for statement in 922 then use ardata->symdef_count as the loop
bound, thus cause a memory overread crush in line 927.

922:  for (counter = 0, set = ardata->symdefs;
923:       counter < ardata->symdef_count;
924:       counter++, set++, rbase += BSD_SYMDEF_SIZE)
925:    {
926:      set->name = H_GET_32 (abfd, rbase) + stringbase;
927:      set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
928:    }

Here paste the gdb crash stack:

Program received signal SIGSEGV, Segmentation fault.
bfd_getl32 (p=0x811b000) at libbfd.c:623
623       v |= (unsigned long) addr[1] << 8;
(gdb) bt
#0  bfd_getl32 (p=0x811b000) at libbfd.c:623
#1  0x0804d5cd in do_slurp_bsd_armap (address@hidden)
    at archive.c:927
#2  0x0804e877 in bfd_slurp_armap (abfd=0x80faa50) at archive.c:1119
#3  0x0804e5cb in bfd_generic_archive_p (abfd=0x80faa50) at archive.c:809
#4  0x08056720 in bfd_check_format_matches (address@hidden, 
    address@hidden, address@hidden)
    at format.c:215
#5  0x08056a8f in bfd_check_format (address@hidden, 
    address@hidden) at format.c:95
#6  0x0804bf81 in display_file (filename=0xbfffeabe "exploit_file")
    at nm.c:1210
#7  0x0804a115 in main (argc=2, argv=0xbfffe814) at nm.c:1688

The attacker may create more sophisticated exploit to cause a memory leak, thus
access privileged information nearby and other unknown effect.

Sincerely,
Ke Yang,Institute of Software Chinese Academy of Sciences
Hengtai Ma,Institute of Software Chinese Academy of Sciences
Xuefei Wang,Institute of Software Chinese Academy of Sciences

-- 
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]