[Bug binutils/25306] New: Null Pointer Dereference in bfd/pef.c:bfd_pef_parse_symbols()
https://sourceware.org/bugzilla/show_bug.cgi?id=25306 Bug ID: 25306 Summary: Null Pointer Dereference in bfd/pef.c:bfd_pef_parse_symbols() Product: binutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: v.manhnd at vincss dot net Target Milestone: --- Created attachment 12139 --> https://sourceware.org/bugzilla/attachment.cgi?id=12139&action=edit The crash PoC Hello, There is a null pointer dereference in bfd/pef.c:bfd_pef_parse_symbols(). ## Analysis Look at the following code in bfd/pef.c:bfd_pef_parse_symbols(): --Code if (codesec != NULL) { codelen = codesec->size; codebuf = bfd_malloc (codelen); if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0) goto end; if (bfd_bread ((void *) codebuf, codelen, abfd) != codelen) goto end; } --- In the code above, codebuf is allocated without checking if the return pointer is null, which makes the writing to codebuf by bfd_bread invalid. ## Reproduce The attachment makes objdump crashes provided objdump is built in 32-bit. --Log-- root@manh-ubuntu16:~/fuzz/fuzz_binutils# binutils-gdb-gcc-32/binutils/objdump -x crash-objdump crash-objdump: file format pef crash-objdump architecture: powerpc:common64, flags 0x01ff: HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, DYNAMIC, WP_TEXT, D_PAGED start address 0x0630 Segmentation fault (core dumped) --- Tested with version 39aa149769fd05fb6fade43bd41c1d7b6d63d06b of github.com/bminor/binutils-gdb -- Thanks & Regards, Nguyen Duc Manh VinCSS (a member of Vingroup) [M] (+84) 346136886 [E] v.man...@vincss.net [W] www.vincss.net -- You are receiving this mail because: You are on the CC list for the bug.
[Bug binutils/25307] New: Heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs()
https://sourceware.org/bugzilla/show_bug.cgi?id=25307 Bug ID: 25307 Summary: Heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs() Product: binutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: v.manhnd at vincss dot net Target Milestone: --- Created attachment 12140 --> https://sourceware.org/bugzilla/attachment.cgi?id=12140&action=edit PoC Hello, There is a heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs() ## Analysis Look at the following code: --Code--- 802:if ((codepos + 4) > codelen) 803: break; 804: 805:ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &sym_index); -- At line 802, it checks if codepos + 4 < codelen. But at line 805, bfd_pef_parse_function_stub reads (codebuf + codepos) with size 24. This could pass the end of codebuf. ## Reproduction The attachment makes objdump crash provided objdump is built with address sanitizer. --Version-- Tested with version 39aa149769fd05fb6fade43bd41c1d7b6d63d06b of github.com/bminor/binutils-gdb --Compilation-- root@manh-ubuntu16:~/fuzz/fuzz_binutils# ./configure --disable-gdb --enable-targets=all CC=gcc CXX=g++ CFLAGS='-fsanitize=address -O0 -ggdb3' CXXFLAGS='-fsanitize=address -O0 -ggdb3' && make -j4 Log Crash-- root@manh-ubuntu16:~/fuzz/fuzz_binutils# ./binutils-gdb-asan-64-O0/binutils/objdump -x crash-objdump3 crash-objdump3: file format pef crash-objdump3 architecture: powerpc:common64, flags 0x01ff: HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, DYNAMIC, WP_TEXT, D_PAGED start address 0x01c0 = ==32000==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6250e9e4 at pc 0x00837265 bp 0x7ffea4e6cf30 sp 0x7ffea4e6cf20 READ of size 1 at 0x6250e9e4 thread T0 #0 0x837264 in bfd_getb32 /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:682 #1 0x12a204b in bfd_pef_parse_function_stub /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:709 #2 0x12a256a in bfd_pef_parse_function_stubs /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:805 #3 0x12a2f9a in bfd_pef_parse_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:929 #4 0x12a30ba in bfd_pef_count_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:951 #5 0x12a30d4 in bfd_pef_get_symtab_upper_bound /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:957 #6 0x4058a9 in slurp_symtab objdump.c:705 #7 0x414e52 in dump_bfd objdump.c:4037 #8 0x41557a in display_object_bfd objdump.c:4165 #9 0x41587a in display_any_bfd objdump.c:4255 #10 0x4158ef in display_file objdump.c:4276 #11 0x416a93 in main objdump.c:4603 #12 0x7f6f3f94382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #13 0x403838 in _start (/root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/binutils/objdump+0x403838) 0x6250e9e4 is located 0 bytes to the right of 8420-byte region [0x6250c900,0x6250e9e4) allocated by thread T0 here: #0 0x7f6f3ff89602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x8366e0 in bfd_malloc /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:275 #2 0x12a2d32 in bfd_pef_parse_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:899 #3 0x12a30ba in bfd_pef_count_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:951 #4 0x12a30d4 in bfd_pef_get_symtab_upper_bound /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:957 #5 0x4058a9 in slurp_symtab objdump.c:705 #6 0x414e52 in dump_bfd objdump.c:4037 #7 0x41557a in display_object_bfd objdump.c:4165 #8 0x41587a in display_any_bfd objdump.c:4255 #9 0x4158ef in display_file objdump.c:4276 #10 0x416a93 in main objdump.c:4603 #11 0x7f6f3f94382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) SUMMARY: AddressSanitizer: heap-buffer-overflow /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:682 bfd_getb32 Shadow bytes around the buggy address: 0x0c4a7fff9ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a7fff9cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a7fff9d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a7fff9d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a7fff9d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c4a7fff9d30: 00 00 00 00 00 00 00 00 00 00 00 00[04]fa fa fa 0x0c4a7fff9d40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a7fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a7fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa
[Bug binutils/25308] New: Multiple null pointer dereferencs in bfd module due to not checking return value of bfd_malloc
https://sourceware.org/bugzilla/show_bug.cgi?id=25308 Bug ID: 25308 Summary: Multiple null pointer dereferencs in bfd module due to not checking return value of bfd_malloc Product: binutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: v.manhnd at vincss dot net Target Milestone: --- Created attachment 12141 --> https://sourceware.org/bugzilla/attachment.cgi?id=12141&action=edit Crashes due to not checking return value of bfd_malloc There are multiple null pointer dereferences in bfd module due to calling bfd_malloc without checking if the return pointer is null. ## Analysis Here is the list of vulnerable issues: ### Issue 1 In bfd/pef.c:bfd_pef_scan_start_address(), loaderbuf is malloced without checking if the return pointer is null. Later, loaderbuf is feeded to bfd_read => Null pointer derefence. -- loaderbuf = bfd_malloc (loaderlen); if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) goto error; if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen) goto error; -- ### Issue 2, 3 In bfd/pef.c:bfd_pef_parse_function_stubs(), libraries and imports are malloced without checking the return values. Later, they are passed to bfd_pef_parse_imported_library and bfd_pef_parse_imported_symbol: -- libraries = bfd_malloc (header.imported_library_count * sizeof (bfd_pef_imported_library)); imports = bfd_malloc (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol)); ... ret = bfd_pef_parse_imported_library (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]); ... ret = (bfd_pef_parse_imported_symbol (abfd, loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4), 4, &imports[i])); -- ### Issue 4, 5 In bfd, pef.c:bfd_pef_parse_symbols(), codebuf and loadersec are malloced without checking the return values. Later, they are passed to bfd_read: -- codesec = bfd_get_section_by_name (abfd, "code"); if (codesec != NULL) { codelen = codesec->size; codebuf = bfd_malloc (codelen); if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0) goto end; if (bfd_bread ((void *) codebuf, codelen, abfd) != codelen) goto end; } loadersec = bfd_get_section_by_name (abfd, "loader"); if (loadersec != NULL) { loaderlen = loadersec->size; loaderbuf = bfd_malloc (loaderlen); if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) goto end; if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen) goto end; } --- ### Issue 6 In bfd/pef.c:bfd_pef_print_loader_section(), loaderbuf is malloced without checking the return value. Later, loaderbuf is passed to bfd_bread: --- loaderbuf = bfd_malloc (loaderlen); if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0 || bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen || loaderlen < 56 || bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header) < 0) { free (loaderbuf); return -1; } --- ### Issue 7 In bfd/mach-o.c:bfd_mach_o_core_fetch_environment(), dsym_filename is passed to sprintf: --- dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename) + strlen (dsym_subdir) + 1 + strlen (base_basename) + 1); sprintf (dsym_filename, "%s%s/%s", base_bfd->filename, dsym_subdir, base_basename); --- ### Issue 8 In bfd/elf-properties.c/_bfd_elf_convert_gnu_properties(), contents is malloced without checking the return value. Later, contents is passed to elf_write_gnu_properties: --- if (size > bfd_section_size (isec)) { contents = (bfd_byte *) bfd_malloc (size); free (*ptr); *ptr = contents; } else contents = *ptr; *ptr_size = size; /* Generate the output .note.gnu.property section. */ elf_write_gnu_properties (ibfd, contents, list, size, 1 << align_shift); --- ### Issue 9 In bfd/elf32-arm.c:bfd_elf32_arm_vfp11_fix_veneer_locations(), tmp_name is malloced without checking the return value. Later, tmp_name is passed to sprintf: --- tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10); ... sprintf (tmp_name, VFP11