Bug 23110

Summary: objcopy segmentation fault
Product: binutils Reporter: Guodong Zhu <donald.zgd>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Severity: normal CC: nickc
Priority: P2    
Version: 2.31   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: the malformed crash input

Description Guodong Zhu 2018-04-24 09:05:10 UTC
Created attachment 10974 [details]
the malformed crash input

When objcopy copying private info(in file bfd/pex64igen.c function: "_bfd_pex64_bfd_copy_private_bfd_data_common()""), it has an unbounded loop that increase the value of (external_IMAGE_DEBUG_DIRECTORY) *edd so that the address exceed its own memory region, results into an unwrittable memory space.

# ------------
# Cmdline:
$ objcopy /tmp/objcopy_crash.input /dev/null

# ------------
# gdb output
Program received signal SIGSEGV, Segmentation fault.
0x0000000000431d9d in bfd_putl32 (data=4194304, p=0x7ffff780901e) at ../../bfd/libbfd.c:775
775       addr[0] = data & 0xff;
(gdb) bt
#0  0x0000000000431d9d in bfd_putl32 (data=4194304, p=0x7ffff780901e) at ../../bfd/libbfd.c:775
#1  0x00000000004e2888 in _bfd_pex64i_swap_debugdir_out (abfd=0x788290, inp=0x7fffffffdc70, extp=0x7ffff780901e) at pex64igen.c:1135
#2  0x00000000004e706d in _bfd_pex64_bfd_copy_private_bfd_data_common (ibfd=0x784ec0, obfd=0x788290) at pex64igen.c:3016
#3  0x00000000004d8983 in pe_bfd_copy_private_bfd_data (ibfd=0x784ec0, obfd=0x788290) at ../../bfd/peicode.h:361
#4  0x00000000004082b9 in copy_object (ibfd=0x784ec0, obfd=0x788290, input_arch=0x0) at ../../binutils/objcopy.c:3170
#5  0x0000000000408fea in copy_file (
    input_filename=0x7fffffffe508 "/tmp/objcopy_crash.input",
    output_filename=0x7fffffffe548 "/dev/null", input_target=0x0, output_target=0x535e86 "pei-x86-64", input_arch=0x0)
    at ../../binutils/objcopy.c:3532
#6  0x000000000040d048 in copy_main (argc=3, argv=0x7fffffffe218) at ../../binutils/objcopy.c:5484
#7  0x000000000040d384 in main (argc=3, argv=0x7fffffffe218) at ../../binutils/objcopy.c:5588
(gdb) info registers
rax            0x7ffff780901e   140737345785886
rbx            0x0      0
rcx            0x7ffff780901e   140737345785886
rdx            0x400000 4194304
rsi            0x7ffff780901e   140737345785886
rdi            0x400000 4194304
rbp            0x7fffffffdbc0   0x7fffffffdbc0
rsp            0x7fffffffdbc0   0x7fffffffdbc0
r8             0xe90000 15269888
r9             0x0      0
r10            0x22     34
r11            0x246    582
r12            0x4025c0 4203968
r13            0x7fffffffe210   140737488347664
r14            0x0      0
r15            0x0      0
rip            0x431d9d 0x431d9d <bfd_putl32+30>
eflags         0x10202  [ IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) info proc mappings
process 7663
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0x566000   0x166000        0x0 /tmp/objcopy
            0x765000           0x777000    0x12000   0x165000 /tmp/objcopy
            0x777000           0x77e000     0x7000   0x177000 /tmp/objcopy
            0x77e000           0x7a4000    0x26000        0x0 [heap]
      0x7ffff6978000     0x7ffff7809000   0xe91000        0x0
      0x7ffff7809000     0x7ffff79c9000   0x1c0000        0x0 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff79c9000     0x7ffff7bc9000   0x200000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7bc9000     0x7ffff7bcd000     0x4000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7bcd000     0x7ffff7bcf000     0x2000   0x1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7bcf000     0x7ffff7bd3000     0x4000        0x0
      0x7ffff7bd3000     0x7ffff7bd6000     0x3000        0x0 /lib/x86_64-linux-gnu/libdl-2.23.so
      0x7ffff7bd6000     0x7ffff7dd5000   0x1ff000     0x3000 /lib/x86_64-linux-gnu/libdl-2.23.so
      0x7ffff7dd5000     0x7ffff7dd6000     0x1000     0x2000 /lib/x86_64-linux-gnu/libdl-2.23.so
      0x7ffff7dd6000     0x7ffff7dd7000     0x1000     0x3000 /lib/x86_64-linux-gnu/libdl-2.23.so
      0x7ffff7dd7000     0x7ffff7dfd000    0x26000        0x0 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7e49000     0x7ffff7fe1000   0x198000        0x0 /usr/lib/locale/locale-archive
      0x7ffff7fe1000     0x7ffff7fe5000     0x4000        0x0
      0x7ffff7ff0000     0x7ffff7ff7000     0x7000        0x0 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
      0x7ffff7ff7000     0x7ffff7ffa000     0x3000        0x0 [vvar]
      0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x25000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x26000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]

# ------------
# Environment
$ uname -a
Linux 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial

# ------------------------------
# Tested on the following two objcopy versions
# 1.
$ git rev-parse HEAD
# 2.
$ /usr/bin/objcopy --version
GNU objcopy (GNU Binutils for Ubuntu) 2.26.1
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

# ------------------------------
This bug was found by Guodong Zhu and Kang Li with Team Seri0us at 360.
Comment 1 Nick Clifton 2018-04-24 15:26:51 UTC
*** Bug 23111 has been marked as a duplicate of this bug. ***
Comment 2 Nick Clifton 2018-04-24 15:29:56 UTC
*** Bug 23112 has been marked as a duplicate of this bug. ***
Comment 3 Sourceware Commits 2018-04-24 15:33:18 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:


commit aa4a8c2a2a67545e90c877162c53cc9de42dc8b4
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Apr 24 16:31:27 2018 +0100

    Fix an illegal memory access when copying a PE format file with corrupt debug information.
    	PR 23110
    	* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Check for
    	a negative PE_DEBUG_DATA size before iterating over the debug data.
Comment 4 Nick Clifton 2018-04-24 15:40:50 UTC
Hi Guodong,

  Thanks for reporting this bug.  I have applied a small patch to the BFD
  library to check for a negative sized PE_DEBUG_DATA entry before starting
  the loop to iterate over the debug data, so this problem should now be