public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug gdb/28017] Out of bounds vector access when setting breakpoint on mach-o (macOS) executable
Date: Mon, 28 Jun 2021 19:31:50 +0000	[thread overview]
Message-ID: <bug-28017-4717-kF2qku1qI4@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-28017-4717@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=28017

--- Comment #2 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

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

commit 2608aff5526471705d6e24340301f3753fc43e35
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Mon Jun 28 15:28:49 2021 -0400

    gdb: use gdb_bfd_count_sections in macho_symfile_offsets

    When loading a mach-o (macOS) executable and trying to set a breakpoint,
    a GDB built with ASan or -D_GLIBCXX_DEBUG will crash with an
    out-of-bound vector access.  This can be reproduced on Linux using the
    repro files in bug 28017 [1]:

        $ ./gdb -nx --data-directory=data-directory -q repro/test -ex "b main"
-batch
        /usr/include/c++/11.1.0/debug/vector:445:
        In function:
            std::__debug::vector<_Tp, _Allocator>::const_reference
            std::__debug::vector<_Tp,
            _Allocator>::operator[](std::__debug::vector<_Tp,
            _Allocator>::size_type) const [with _Tp = long unsigned int;
_Allocator
            = std::allocator<long unsigned int>; std::__debug::vector<_Tp,
            _Allocator>::const_reference = const long unsigned int&;
            std::__debug::vector<_Tp, _Allocator>::size_type = long unsigned
int]

        Error: attempt to subscript container with out-of-bounds index 13, but
        container only holds 13 elements.

        Objects involved in the operation:
            sequence "this" @ 0x0x61300000a590 {
              type = std::__debug::vector<unsigned long,
std::allocator<unsigned long> >;
            }

    The out-of-bound access happens here:

        #0  0x00007ffff6405d22 in raise () from /usr/lib/libc.so.6
        #1  0x00007ffff63ef862 in abort () from /usr/lib/libc.so.6
        #2  0x00007ffff664e21e in __gnu_debug::_Error_formatter::_M_error()
const [clone .cold] from /usr/lib/libstdc++.so.6
        #3  0x000055555699e5ff in std::__debug::vector<unsigned long,
std::allocator<unsigned long> >::operator[] (this=0x61300000a590, __n=13) at
/usr/include/c++/11.1.0/debug/vector:445
        #4  0x0000555556a58c17 in objfile::section_offset (this=0x61300000a4c0,
section=0x55555bbe4ac0 <_bfd_std_section>) at
/home/simark/src/binutils-gdb/gdb/objfiles.h:644
        #5  0x0000555556a58cac in obj_section::offset (this=0x62100016d2a8) at
/home/simark/src/binutils-gdb/gdb/objfiles.h:838
        #6  0x0000555556a58cfa in obj_section::addr (this=0x62100016d2a8) at
/home/simark/src/binutils-gdb/gdb/objfiles.h:850
        #7  0x000055555779f5f7 in sort_cmp (sect1=0x62100016d2a8,
sect2=0x62100016d170) at /home/simark/src/binutils-gdb/gdb/objfiles.c:902
        #8  0x00005555577aae35 in __gnu_cxx::__ops::_Iter_comp_iter<bool
(*)(obj_section const*, obj_section const*)>::operator()<obj_section**,
obj_section**> (this=0x7fffffffa9e0, __it1=0x60c000015970,
__it2=0x60c000015940) at /usr/include/c++/11.1.0/bits/predefined_ops.h:158
        #9  0x00005555577aa2b8 in std::__insertion_sort<obj_section**,
__gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section
const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at
/usr/include/c++/11.1.0/bits/stl_algo.h:1826
        #10 0x00005555577a8e26 in std::__final_insertion_sort<obj_section**,
__gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section
const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at
/usr/include/c++/11.1.0/bits/stl_algo.h:1871
        #11 0x00005555577a723c in std::__sort<obj_section**,
__gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section
const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at
/usr/include/c++/11.1.0/bits/stl_algo.h:1957
        #12 0x00005555577a50f4 in std::sort<obj_section**, bool (*)(obj_section
const*, obj_section const*)> (__first=0x60c000015940, __last=0x60c0000159c0,
__comp=0x55555779f4e7 <sort_cmp(obj_section const*, obj_section const*)>) at
/usr/include/c++/11.1.0/bits/stl_algo.h:4875
        #13 0x00005555577a147e in update_section_map (pspace=0x61200001d2c0,
pmap=0x6030000d40b0, pmap_size=0x6030000d40b8) at
/home/simark/src/binutils-gdb/gdb/objfiles.c:1165
        #14 0x00005555577a19a0 in find_pc_section (pc=0x100003fa0) at
/home/simark/src/binutils-gdb/gdb/objfiles.c:1212
        #15 0x00005555576dd39e in lookup_minimal_symbol_by_pc_section
(pc_in=0x100003fa0, section=0x0, prefer=lookup_msym_prefer::TEXT, previous=0x0)
at /home/simark/src/binutils-gdb/gdb/minsyms.c:750
        #16 0x00005555576de552 in lookup_minimal_symbol_by_pc (pc=0x100003fa0)
at /home/simark/src/binutils-gdb/gdb/minsyms.c:986
        #17 0x0000555557d44b54 in find_pc_sect_line (pc=0x100003fa0,
section=0x62100016d170, notcurrent=0) at
/home/simark/src/binutils-gdb/gdb/symtab.c:3163
        #18 0x0000555557d489fa in find_function_start_sal_1
(func_addr=0x100003fa0, section=0x62100016d170, funfirstline=true) at
/home/simark/src/binutils-gdb/gdb/symtab.c:3650
        #19 0x0000555557d49015 in find_function_start_sal (sym=0x621000191670,
funfirstline=true) at /home/simark/src/binutils-gdb/gdb/symtab.c:3706
        #20 0x0000555557485283 in symbol_to_sal (result=0x7fffffffbb30,
funfirstline=1, sym=0x621000191670) at
/home/simark/src/binutils-gdb/gdb/linespec.c:4460
        #21 0x00005555574728c2 in convert_linespec_to_sals
(state=0x7fffffffc390, ls=0x7fffffffc3e0) at
/home/simark/src/binutils-gdb/gdb/linespec.c:2335
        #22 0x0000555557475a8e in parse_linespec (parser=0x7fffffffc360,
arg=0x60200007a550 "main", match_type=symbol_name_match_type::WILD) at
/home/simark/src/binutils-gdb/gdb/linespec.c:2716
        #23 0x0000555557479027 in event_location_to_sals
(parser=0x7fffffffc360, location=0x606000097be0) at
/home/simark/src/binutils-gdb/gdb/linespec.c:3173
        #24 0x00005555574798f7 in decode_line_full (location=0x606000097be0,
flags=1, search_pspace=0x0, default_symtab=0x0, default_line=0,
canonical=0x7fffffffcca0, select_mode=0x0, filter=0x0) at
/home/simark/src/binutils-gdb/gdb/linespec.c:3253
        #25 0x0000555556b4949f in parse_breakpoint_sals
(location=0x606000097be0, canonical=0x7fffffffcca0) at
/home/simark/src/binutils-gdb/gdb/breakpoint.c:9134
        #26 0x0000555556b6ce95 in create_sals_from_location_default
(location=0x606000097be0, canonical=0x7fffffffcca0, type_wanted=bp_breakpoint)
at /home/simark/src/binutils-gdb/gdb/breakpoint.c:13819
        #27 0x0000555556b645a6 in bkpt_create_sals_from_location
(location=0x606000097be0, canonical=0x7fffffffcca0, type_wanted=bp_breakpoint)
at /home/simark/src/binutils-gdb/gdb/breakpoint.c:12631
        #28 0x0000555556b4badf in create_breakpoint (gdbarch=0x621000152d10,
location=0x606000097be0, cond_string=0x0, thread=0, extra_string=0x0,
force_condition=false, parse_extra=1, tempflag=0, type_wanted=bp_breakpoint,
ignore_count=0, pending_break_support=AUTO_BOOLEAN_AUTO, ops=0x55555bd728a0
<bkpt_breakpoint_ops>, from_tty=0, enabled=1, internal=0, flags=0) at
/home/simark/src/binutils-gdb/gdb/breakpoint.c:9410
        #29 0x0000555556b4d3b1 in break_command_1 (arg=0x7fffffffe291 "",
flag=0, from_tty=0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9590
        #30 0x0000555556b4dc1b in break_command (arg=0x7fffffffe28d "main",
from_tty=0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9660
        #31 0x0000555556d24ca9 in do_const_cfunc (c=0x61100003a240,
args=0x7fffffffe28d "main", from_tty=0) at
/home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:102
        #32 0x0000555556d2fcd3 in cmd_func (cmd=0x61100003a240,
args=0x7fffffffe28d "main", from_tty=0) at
/home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:2160
        #33 0x0000555557e84e93 in execute_command (p=0x7fffffffe290 "n",
from_tty=0) at /home/simark/src/binutils-gdb/gdb/top.c:674
        #34 0x00005555575a9933 in catch_command_errors (command=0x555557e84043
<execute_command(char const*, int)>, arg=0x7fffffffe28b "b main", from_tty=0,
do_bp_actions=true) at /home/simark/src/binutils-gdb/gdb/main.c:523
        #35 0x00005555575a9fdb in execute_cmdargs (cmdarg_vec=0x7fffffffd910,
file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffd5b0) at
/home/simark/src/binutils-gdb/gdb/main.c:618
        #36 0x00005555575ad48a in captured_main_1 (context=0x7fffffffdd00) at
/home/simark/src/binutils-gdb/gdb/main.c:1322
        #37 0x00005555575ada9c in captured_main (data=0x7fffffffdd00) at
/home/simark/src/binutils-gdb/gdb/main.c:1343
        #38 0x00005555575adb31 in gdb_main (args=0x7fffffffdd00) at
/home/simark/src/binutils-gdb/gdb/main.c:1368
        #39 0x000055555681e179 in main (argc=8, argv=0x7fffffffde78) at
/home/simark/src/binutils-gdb/gdb/gdb.c:32

    The section being dealt with at that moment is the special *COM*
    section:

        (top-gdb) p section.name
        $1 = 0x55555a1bbe60 "*COM*"
        (top-gdb) p section
        $2 = (bfd_section *) 0x55555bbe4ac0 <_bfd_std_section>

    I'm not too sure what this section is for, but this is one of four
    special BFD sections that GDB puts after the regular sections in the
    objfile::sections and objfile::section_offsets lists.  You can check
    gdb_bfd_section_index to see how they are handled.
    gdb_bfd_count_sections returns "+ 4" to account for those sections.

    The problem is that macho_symfile_offsets uses bfd_count_sections
    instead of gdb_bfd_count_sections when allocating the
    objfile::section_offsets vector.  The vector will therefore contain,
    say, 13 elements instead of 17.  When trying to access the section
    offset of the *COM* section, the first after the regular sections, we
    access section_offsets[13], which is out of bounds.

    Fix that by using gdb_bfd_count_sections instead of bfd_count_sections.
    I'm fairly confident that this is correct, as this is what
    default_symfile_offsets does.

    With this patch, the command shown above terminates normally:

        $ ./gdb -nx --data-directory=data-directory -q repro/test -ex "b main"
-batch
        Breakpoint 1 at 0x100003fad: file test.c, line 2.

    [1] https://sourceware.org/bugzilla/show_bug.cgi?id=28017

    gdb/ChangeLog:

            PR gdb/28017
            * machoread.c (macho_symfile_offsets): Use
            gdb_bfd_count_sections to allocate objfile::section_offsets.

    Change-Id: Ic3a56f46f7232e9f24581f8255fc1ab981935450

-- 
You are receiving this mail because:
You are on the CC list for the bug.

  parent reply	other threads:[~2021-06-28 19:31 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-27  2:11 [Bug gdb/28017] New: " simark at simark dot ca
2021-06-27  2:45 ` [Bug gdb/28017] " simark at simark dot ca
2021-06-28 19:31 ` cvs-commit at gcc dot gnu.org [this message]
2021-06-28 19:32 ` simark at simark dot ca

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-28017-4717-kF2qku1qI4@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).