Bug 29948 - AddressSanitizer: heap-buffer-overflow in display_debug_lines_decoded() at dwarf.c:5429
Summary: AddressSanitizer: heap-buffer-overflow in display_debug_lines_decoded() at dw...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.39
: P2 normal
Target Milestone: 2.40
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-12-29 10:12 UTC by 曾思維
Modified: 2022-12-30 11:56 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Generated by my fuzzer and afl-tmin (3.48 KB, application/x-sharedlib)
2022-12-29 10:12 UTC, 曾思維
Details

Note You need to log in before you can comment on or make changes to this bug.
Description 曾思維 2022-12-29 10:12:44 UTC
Created attachment 14542 [details]
Generated by my fuzzer and afl-tmin

# version

$ ./binutils-gdb_asan/binutils/objdump --version
GNU objdump (GNU Binutils) 2.39.50.20221229
Copyright (C) 2022 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.

---------------------------------------------------------------------
# git log

$ git log --oneline -1
c509db05e4f (HEAD -> master, origin/master, origin/HEAD) RISC-V: Simplify riscv_csr_address logic on state enable extension

---------------------------------------------------------------------
# make

$ git clone git://sourceware.org/git/binutils-gdb.git
$ cd binutils-gdb
$ ./configure CFLAGS='-fsanitize=address -g3' CXXFALGS='-fsanitize=address -g3'
$ make

---------------------------------------------------------------------
# ASAN report

$ ./binutils-gdb_asan/binutils/objdump -WL poc
./binutils-gdb_asan/binutils/objdump: Warning: Corrupt attribute block length: 0x30303030

poc:     file format elf64-x86-64

./binutils-gdb_asan/binutils/objdump: poc: invalid string offset 808464432 >= 3321 for section `ld-id'
./binutils-gdb_asan/binutils/objdump: poc: invalid string offset 808464432 >= 3321 for section `ld-id'
./binutils-gdb_asan/binutils/objdump: poc: invalid string offset 808464432 >= 3321 for section `ld-id'

(... too long ignore)

<offset is too big>/00000000000000000000000000000000000:
00000000000000000000000000000000000       321124             0x1a610               x
  Unknown opcode 17 with operands: 
00000000000000000000000000000000000       321177             0x1a640               x
  Unknown opcode 17 with operands: 
=================================================================
==3200753==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000043e0 at pc 0x559f0ca791f7 bp 0x7ffdc57fac00 sp 0x7ffdc57fabf0
READ of size 8 at 0x6060000043e0 thread T0
    #0 0x559f0ca791f6 in display_debug_lines_decoded dwarf.c:5429
    #1 0x559f0ca7a4a2 in display_debug_lines dwarf.c:5673
    #2 0x559f0ca4fbe6 in dump_dwarf_section objdump.c:4420
    #3 0x559f0cb9ec1c in bfd_map_over_sections /home/a13579/fuzz_binutils-gdb/binutils-gdbnew/binutils-gdb_asan/bfd/section.c:1366
    #4 0x559f0ca4fe15 in dump_dwarf objdump.c:4458
    #5 0x559f0ca56432 in dump_bfd objdump.c:5660
    #6 0x559f0ca56807 in display_object_bfd objdump.c:5739
    #7 0x559f0ca56b38 in display_any_bfd objdump.c:5825
    #8 0x559f0ca56bb2 in display_file objdump.c:5846
    #9 0x559f0ca584db in main objdump.c:6254
    #10 0x7f3823abf082 in __libc_start_main ../csu/libc-start.c:308
    #11 0x559f0ca3c3bd in _start (/home/a13579/fuzz_binutils-gdb/binutils-gdbnew/binutils-gdb_asan/binutils/objdump+0x13b3bd)

0x6060000043e0 is located 0 bytes to the right of 64-byte region [0x6060000043a0,0x6060000043e0)
allocated by thread T0 here:
    #0 0x7f3823da0a06 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x559f0ce32e3b in xcalloc xmalloc.c:164
    #2 0x559f0ca7520f in display_debug_lines_decoded dwarf.c:4980
    #3 0x559f0ca7a4a2 in display_debug_lines dwarf.c:5673
    #4 0x559f0ca4fbe6 in dump_dwarf_section objdump.c:4420
    #5 0x559f0cb9ec1c in bfd_map_over_sections /home/a13579/fuzz_binutils-gdb/binutils-gdbnew/binutils-gdb_asan/bfd/section.c:1366
    #6 0x559f0ca4fe15 in dump_dwarf objdump.c:4458
    #7 0x559f0ca56432 in dump_bfd objdump.c:5660
    #8 0x559f0ca56807 in display_object_bfd objdump.c:5739
    #9 0x559f0ca56b38 in display_any_bfd objdump.c:5825
    #10 0x559f0ca56bb2 in display_file objdump.c:5846
    #11 0x559f0ca584db in main objdump.c:6254
    #12 0x7f3823abf082 in __libc_start_main ../csu/libc-start.c:308

SUMMARY: AddressSanitizer: heap-buffer-overflow dwarf.c:5429 in display_debug_lines_decoded
Shadow bytes around the buggy address:
  0x0c0c7fff8820: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff8830: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c7fff8840: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff8850: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff8860: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
=>0x0c0c7fff8870: fa fa fa fa 00 00 00 00 00 00 00 00[fa]fa fa fa
  0x0c0c7fff8880: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff8890: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c7fff88a0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff88b0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff88c0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==3200753==ABORTING
Comment 1 Alan Modra 2022-12-29 12:50:23 UTC
The logic for DW_LNS_set_file needs fixing similar to what we have in bfd/dwarf2.c, in particular, dir == 0 for dwarf<5 should pick up DW_AT_comp_dir if possible rather than just displaying "./".
Comment 2 Sourceware Commits 2022-12-30 11:55:39 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a984f112b015b7d33c3c91230eb4c35695926539

commit a984f112b015b7d33c3c91230eb4c35695926539
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Dec 30 11:41:16 2022 +1030

    PR29948, heap-buffer-overflow in display_debug_lines_decoded
    
    This fixes a couple of places in display_debug_lines_decoded that were
    off by one in checking DWARF5 .debug_line directory indices.  It also
    displays the DWARF5 entry 0 for the program current directory rather
    than "." as is done for pre-DWARF5.  I decided against displaying
    DW_AT_comp_dir for pre-DWARF5 since I figure it is better for readelf
    to minimally interpret debug info.
    
    binutils/
            PR 29948
            * dwarf.c (display_debug_lines_decoded): Display the given
            directory entry 0 for DWARF5.  Properly check directory index
            against number of entries in the table.  Revert to using
            unsigned int for n_directories and associated variables.
            Correct warning messages.
    gas/
            * testsuite/gas/elf/dwarf-5-loc0.d: Update.
Comment 3 Alan Modra 2022-12-30 11:56:11 UTC
Fixed