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 (abfd=abfd@entry=0x80faa50) 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 (abfd=abfd@entry=0x80faa50, format=format@entry=bfd_archive, matching=matching@entry=0x0) at format.c:215 #5 0x08056a8f in bfd_check_format (abfd=abfd@entry=0x80faa50, format=format@entry=bfd_archive) 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 mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils