[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.
- [Bug binutils/19296] New: memory crush(Out of bound read error)caused by insufficient check for parsed_size in archive.c,
0yangke0 at gmail dot com <=