[Bug gdb/24618] New: heap-buffer-overflow in cp_find_first_component_aux

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] New: heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

            Bug ID: 24618
           Summary: heap-buffer-overflow in cp_find_first_component_aux
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Compiling gdb with -lasan and -fsanitizer=address and running tests with export
ASAN_OPTIONS="detect_leaks=0:alloc_dealloc_mismatch=0" and with target board
cc-with-gdb-index, and this commit reverted to avoid running into PR24617:
...
commit 36cd4ba59817473935f781174744e7883ff221ee
Author: Tom de Vries <[hidden email]>
Date:   Thu Apr 18 23:37:33 2019 +0200

    [gdb/testsuite] Fix gdb.base/break-probes.exp with native-gdbserver
...
we get:
...
==31229==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x62500098c93c at pc 0x000000bcc748 bp 0x7ffe39487660 sp 0x7ffe39487658
READ of size 1 at 0x62500098c93c thread T0
    #0 0xbcc747 in cp_find_first_component_aux
/data/gdb_versions/devel/src/gdb/cp-support.c:999
    #1 0xbcc6e9 in cp_find_first_component(char const*)
/data/gdb_versions/devel/src/gdb/cp-support.c:977
    #2 0xcc2cf3 in mapped_index_base::build_name_components()
/data/gdb_versions/devel/src/gdb/dwarf2read.c:4499
    #3 0xcc3322 in dw2_expand_symtabs_matching_symbol
/data/gdb_versions/devel/src/gdb/dwarf2read.c:4552
    #4 0xcc817f in dw2_expand_symtabs_matching
/data/gdb_versions/devel/src/gdb/dwarf2read.c:5228
    #5 0xfe8f48 in iterate_over_all_matching_symtabs
/data/gdb_versions/devel/src/gdb/linespec.c:1147
    #6 0x1003506 in add_matching_symbols_to_info
/data/gdb_versions/devel/src/gdb/linespec.c:4413
    #7 0xffe21b in find_function_symbols
/data/gdb_versions/devel/src/gdb/linespec.c:3886
    #8 0xffe4a2 in find_linespec_symbols
/data/gdb_versions/devel/src/gdb/linespec.c:3914
    #9 0xfee3ad in linespec_parse_basic
/data/gdb_versions/devel/src/gdb/linespec.c:1865
    #10 0xff5128 in parse_linespec
/data/gdb_versions/devel/src/gdb/linespec.c:2655
    #11 0xff8872 in event_location_to_sals
/data/gdb_versions/devel/src/gdb/linespec.c:3150
    #12 0xff90a8 in decode_line_full(event_location const*, int,
program_space*, symtab*, int, linespec_result*, char const*, char const*)
/data/gdb_versions/devel/src/gdb/linespec.c:3230
    #13 0x9ce449 in parse_breakpoint_sals
/data/gdb_versions/devel/src/gdb/breakpoint.c:9057
    #14 0x9ea022 in create_sals_from_location_default
/data/gdb_versions/devel/src/gdb/breakpoint.c:13708
    #15 0x9e2c1f in bkpt_create_sals_from_location
/data/gdb_versions/devel/src/gdb/breakpoint.c:12514
    #16 0x9cff06 in create_breakpoint(gdbarch*, event_location const*, char
const*, int, char const*, int, int, bptype, int, auto_boolean, breakpoint_ops
const*, int, int, int, unsigned int)
/data/gdb_versions/devel/src/gdb/breakpoint.c:9238
    #17 0x9d114a in break_command_1
/data/gdb_versions/devel/src/gdb/breakpoint.c:9402
    #18 0x9d1b60 in break_command(char const*, int)
/data/gdb_versions/devel/src/gdb/breakpoint.c:9473
    #19 0xac96aa in do_const_cfunc
/data/gdb_versions/devel/src/gdb/cli/cli-decode.c:106
    #20 0xad0e5a in cmd_func(cmd_list_element*, char const*, int)
/data/gdb_versions/devel/src/gdb/cli/cli-decode.c:1892
    #21 0x15226f6 in execute_command(char const*, int)
/data/gdb_versions/devel/src/gdb/top.c:630
    #22 0xddde37 in command_handler(char const*)
/data/gdb_versions/devel/src/gdb/event-top.c:586
    #23 0xdde7c1 in command_line_handler(std::unique_ptr<char,
gdb::xfree_deleter<char> >&&) /data/gdb_versions/devel/src/gdb/event-top.c:773
    #24 0xddc9e8 in gdb_rl_callback_handler
/data/gdb_versions/devel/src/gdb/event-top.c:217
    #25 0x16f2198 in rl_callback_read_char
/data/gdb_versions/devel/src/readline/callback.c:220
    #26 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept
/data/gdb_versions/devel/src/gdb/event-top.c:175
    #27 0xddc773 in gdb_rl_callback_read_char_wrapper
/data/gdb_versions/devel/src/gdb/event-top.c:192
    #28 0xddd9f5 in stdin_event_handler(int, void*)
/data/gdb_versions/devel/src/gdb/event-top.c:514
    #29 0xdd7d8f in handle_file_event
/data/gdb_versions/devel/src/gdb/event-loop.c:731
    #30 0xdd8607 in gdb_wait_for_event
/data/gdb_versions/devel/src/gdb/event-loop.c:857
    #31 0xdd629c in gdb_do_one_event()
/data/gdb_versions/devel/src/gdb/event-loop.c:321
    #32 0xdd6344 in start_event_loop()
/data/gdb_versions/devel/src/gdb/event-loop.c:370
    #33 0x10a7715 in captured_command_loop
/data/gdb_versions/devel/src/gdb/main.c:331
    #34 0x10aa548 in captured_main /data/gdb_versions/devel/src/gdb/main.c:1173
    #35 0x10aa5d8 in gdb_main(captured_main_args*)
/data/gdb_versions/devel/src/gdb/main.c:1188
    #36 0x87bd35 in main /data/gdb_versions/devel/src/gdb/gdb.c:32
    #37 0x7f16e1434f89 in __libc_start_main (/lib64/libc.so.6+0x20f89)
    #38 0x87bb49 in _start (/data/gdb_versions/devel/build/gdb/gdb+0x87bb49)

0x62500098c93c is located 0 bytes to the right of 8252-byte region
[0x62500098a900,0x62500098c93c)
allocated by thread T0 here:
    #0 0x7f16e359a600 in malloc (/usr/lib64/libasan.so.5+0xeb600)
    #1 0x1742ddf in bfd_malloc /data/gdb_versions/devel/src/bfd/libbfd.c:275
    #2 0x1738824 in bfd_get_full_section_contents
/data/gdb_versions/devel/src/bfd/compress.c:253
    #3 0xe30044 in gdb_bfd_map_section(bfd_section*, unsigned long*)
/data/gdb_versions/devel/src/gdb/gdb_bfd.c:704
    #4 0xcb56bf in dwarf2_read_section(objfile*, dwarf2_section_info*)
/data/gdb_versions/devel/src/gdb/dwarf2read.c:2539
    #5 0xd5bcd0 in get_gdb_index_contents_from_section<dwarf2_per_objfile>
/data/gdb_versions/devel/src/gdb/dwarf2read.c:6217
    #6 0xd7fc7d in gdb::function_view<gdb::array_view<unsigned char const>
(objfile*, dwarf2_per_objfile*)>::bind<gdb::array_view<unsigned char const>,
objfile*, dwarf2_per_objfile*>(gdb::array_view<unsigned char const>
(*)(objfile*, dwarf2_per_objfile*))::{lambda(gdb::fv_detail::erased_callable,
objfile*, dwarf2_per_objfile*)#1}::operator()(gdb::fv_detail::erased_callable,
objfile*, dwarf2_per_objfile*) const
/data/gdb_versions/devel/src/gdb/common/function-view.h:284
    #7 0xd7fddd in gdb::function_view<gdb::array_view<unsigned char const>
(objfile*, dwarf2_per_objfile*)>::bind<gdb::array_view<unsigned char const>,
objfile*, dwarf2_per_objfile*>(gdb::array_view<unsigned char const>
(*)(objfile*, dwarf2_per_objfile*))::{lambda(gdb::fv_detail::erased_callable,
objfile*, dwarf2_per_objfile*)#1}::_FUN(gdb::fv_detail::erased_callable,
objfile*, dwarf2_per_objfile*)
/data/gdb_versions/devel/src/gdb/common/function-view.h:278
    #8 0xd730cf in gdb::function_view<gdb::array_view<unsigned char const>
(objfile*, dwarf2_per_objfile*)>::operator()(objfile*, dwarf2_per_objfile*)
const /data/gdb_versions/devel/src/gdb/common/function-view.h:247
    #9 0xcbc7ee in dwarf2_read_gdb_index
/data/gdb_versions/devel/src/gdb/dwarf2read.c:3582
    #10 0xcce731 in dwarf2_initialize_objfile(objfile*, dw_index_kind*)
/data/gdb_versions/devel/src/gdb/dwarf2read.c:6297
    #11 0xdb88c4 in elf_symfile_read
/data/gdb_versions/devel/src/gdb/elfread.c:1256
    #12 0x141262a in read_symbols
/data/gdb_versions/devel/src/gdb/symfile.c:798
    #13 0x14140a7 in syms_from_objfile_1
/data/gdb_versions/devel/src/gdb/symfile.c:1000
    #14 0x1414393 in syms_from_objfile
/data/gdb_versions/devel/src/gdb/symfile.c:1017
    #15 0x1414fb7 in symbol_file_add_with_addrs
/data/gdb_versions/devel/src/gdb/symfile.c:1124
    #16 0x14159b7 in symbol_file_add_from_bfd(bfd*, char const*,
enum_flags<symfile_add_flag>, std::vector<other_sections,
std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*)
/data/gdb_versions/devel/src/gdb/symfile.c:1203
    #17 0x1415b6c in symbol_file_add(char const*, enum_flags<symfile_add_flag>,
std::vector<other_sections, std::allocator<other_sections> >*,
enum_flags<objfile_flag>) /data/gdb_versions/devel/src/gdb/symfile.c:1216
    #18 0x1415f2f in symbol_file_add_main_1
/data/gdb_versions/devel/src/gdb/symfile.c:1240
    #19 0x1418599 in symbol_file_command(char const*, int)
/data/gdb_versions/devel/src/gdb/symfile.c:1675
    #20 0xde2fa6 in file_command /data/gdb_versions/devel/src/gdb/exec.c:433
    #21 0xac96aa in do_const_cfunc
/data/gdb_versions/devel/src/gdb/cli/cli-decode.c:106
    #22 0xad0e5a in cmd_func(cmd_list_element*, char const*, int)
/data/gdb_versions/devel/src/gdb/cli/cli-decode.c:1892
    #23 0x15226f6 in execute_command(char const*, int)
/data/gdb_versions/devel/src/gdb/top.c:630
    #24 0xddde37 in command_handler(char const*)
/data/gdb_versions/devel/src/gdb/event-top.c:586
    #25 0xdde7c1 in command_line_handler(std::unique_ptr<char,
gdb::xfree_deleter<char> >&&) /data/gdb_versions/devel/src/gdb/event-top.c:773
    #26 0xddc9e8 in gdb_rl_callback_handler
/data/gdb_versions/devel/src/gdb/event-top.c:217
    #27 0x16f2198 in rl_callback_read_char
/data/gdb_versions/devel/src/readline/callback.c:220
    #28 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept
/data/gdb_versions/devel/src/gdb/event-top.c:175
    #29 0xddc773 in gdb_rl_callback_read_char_wrapper
/data/gdb_versions/devel/src/gdb/event-top.c:192

SUMMARY: AddressSanitizer: heap-buffer-overflow
/data/gdb_versions/devel/src/gdb/cp-support.c:999 in
cp_find_first_component_aux
Shadow bytes around the buggy address:
  0x0c4a801298d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a801298e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a801298f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a80129900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a80129910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a80129920: 00 00 00 00 00 00 00[04]fa fa fa fa fa fa fa fa
  0x0c4a80129930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80129940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80129950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80129960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80129970: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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
==31229==ABORTING
...

Triggers for gdb.arch/amd64-init-x87-values.exp, gdb.base/gnu-ifunc.exp,
gdb.base/info-fun.exp, gdb.base/info-shared.exp, gdb.base/jit-simple,
gdb.base/jit.so, gdb.base/jit, gdb.base/solib-display, gdb.base/solib-weak,
gdb.btrace/dlopen, and more.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

Tom de Vries <vries at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simark at simark dot ca

--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
Simon, does this change look ok to you?
...
$ git diff
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index f48b931a3f..802fd380ec 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -212,7 +212,7 @@ struct mapped_index final : public mapped_index_base
   bool symbol_name_slot_invalid (offset_type idx) const override
   {
     const auto &bucket = this->symbol_table[idx];
-    return bucket.name == 0 && bucket.vec;
+    return bucket.name == 0 && bucket.vec == 0;
   }

   /* Convenience method to get at the name of the symbol at IDX in the
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
In reply to this post by adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #1)

> Simon, does this change look ok to you?
> ...
> $ git diff
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index f48b931a3f..802fd380ec 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -212,7 +212,7 @@ struct mapped_index final : public mapped_index_base
>    bool symbol_name_slot_invalid (offset_type idx) const override
>    {
>      const auto &bucket = this->symbol_table[idx];
> -    return bucket.name == 0 && bucket.vec;
> +    return bucket.name == 0 && bucket.vec == 0;
>    }
>  
>    /* Convenience method to get at the name of the symbol at IDX in the
> ...

Given that here (
https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html#Index-Section-Format
) we have:
...
Each slot in the hash table consists of a pair of offset_type values. The first
value is the offset of the symbol’s name in the constant pool. The second value
is the offset of the CU vector in the constant pool.

If both values are 0, then this slot in the hash table is empty. This is ok
because while 0 is a valid constant pool index, it cannot be a valid index for
both a string and a CU vector.
...

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
In reply to this post by adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

--- Comment #3 from Tom de Vries <vries at gcc dot gnu.org> ---
Submitted patch: https://sourceware.org/ml/gdb-patches/2019-05/msg00574.html

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
In reply to this post by adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

--- Comment #4 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <[hidden email]>:

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

commit 9ab084121f50a6858b7298de6c5326cee3687c43
Author: Tom de Vries <[hidden email]>
Date:   Mon Jun 10 20:27:09 2019 +0200

    [gdb] Fix heap-buffer-overflow in cp_find_first_component_aux

    When compiling gdb with '-lasan -fsanitizer=address' and running tests
with:
    - export ASAN_OPTIONS="detect_leaks=0:alloc_dealloc_mismatch=0",
    - target board cc-with-gdb-index,
    - the "[gdb/testsuite] Fix gdb.base/break-probes.exp with native-gdbserver"
      commit reverted to avoid running into PR24617,
    we get with gdb.arch/amd64-init-x87-values.exp:
    ...
    ==31229==ERROR: AddressSanitizer: heap-buffer-overflow on address \
      0x62500098c93c at pc 0x000000bcc748 bp 0x7ffe39487660 sp 0x7ffe39487658
    READ of size 1 at 0x62500098c93c thread T0
        #0 0xbcc747 in cp_find_first_component_aux src/gdb/cp-support.c:999
        #1 0xbcc6e9 in cp_find_first_component(char const*) \
                       src/gdb/cp-support.c:977
        #2 0xcc2cf3 in mapped_index_base::build_name_components() \
                       src/gdb/dwarf2read.c:4499
        #3 0xcc3322 in dw2_expand_symtabs_matching_symbol
src/gdb/dwarf2read.c:4552
        #4 0xcc817f in dw2_expand_symtabs_matching src/gdb/dwarf2read.c:5228
        #5 0xfe8f48 in iterate_over_all_matching_symtabs
src/gdb/linespec.c:1147
        #6 0x1003506 in add_matching_symbols_to_info src/gdb/linespec.c:4413
        #7 0xffe21b in find_function_symbols src/gdb/linespec.c:3886
        #8 0xffe4a2 in find_linespec_symbols src/gdb/linespec.c:3914
        #9 0xfee3ad in linespec_parse_basic src/gdb/linespec.c:1865
        #10 0xff5128 in parse_linespec src/gdb/linespec.c:2655
        #11 0xff8872 in event_location_to_sals src/gdb/linespec.c:3150
        #12 0xff90a8 in decode_line_full(event_location const*, int, \
                        program_space*, symtab*, int, linespec_result*, \
                    char const*, char const*) src/gdb/linespec.c:3230
        #13 0x9ce449 in parse_breakpoint_sals src/gdb/breakpoint.c:9057
        #14 0x9ea022 in create_sals_from_location_default
src/gdb/breakpoint.c:13708
        #15 0x9e2c1f in bkpt_create_sals_from_location
src/gdb/breakpoint.c:12514
        #16 0x9cff06 in create_breakpoint(gdbarch*, event_location const*, \
                        char const*, int, char const*, int, int, bptype, int, \
                    auto_boolean, breakpoint_ops const*, int, int, int, \
                    unsigned int) src/gdb/breakpoint.c:9238
        #17 0x9d114a in break_command_1 src/gdb/breakpoint.c:9402
        #18 0x9d1b60 in break_command(char const*, int)
src/gdb/breakpoint.c:9473
        #19 0xac96aa in do_const_cfunc src/gdb/cli/cli-decode.c:106
        #20 0xad0e5a in cmd_func(cmd_list_element*, char const*, int) \
                        src/gdb/cli/cli-decode.c:1892
        #21 0x15226f6 in execute_command(char const*, int) src/gdb/top.c:630
        #22 0xddde37 in command_handler(char const*) src/gdb/event-top.c:586
        #23 0xdde7c1 in command_line_handler(std::unique_ptr<char, \
                        gdb::xfree_deleter<char> >&&) src/gdb/event-top.c:773
        #24 0xddc9e8 in gdb_rl_callback_handler src/gdb/event-top.c:217
        #25 0x16f2198 in rl_callback_read_char src/readline/callback.c:220
        #26 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept \
                        src/gdb/event-top.c:175
        #27 0xddc773 in gdb_rl_callback_read_char_wrapper
src/gdb/event-top.c:192
        #28 0xddd9f5 in stdin_event_handler(int, void*) src/gdb/event-top.c:514
        #29 0xdd7d8f in handle_file_event src/gdb/event-loop.c:731
        #30 0xdd8607 in gdb_wait_for_event src/gdb/event-loop.c:857
        #31 0xdd629c in gdb_do_one_event() src/gdb/event-loop.c:321
        #32 0xdd6344 in start_event_loop() src/gdb/event-loop.c:370
        #33 0x10a7715 in captured_command_loop src/gdb/main.c:331
        #34 0x10aa548 in captured_main src/gdb/main.c:1173
        #35 0x10aa5d8 in gdb_main(captured_main_args*) src/gdb/main.c:1188
        #36 0x87bd35 in main src/gdb/gdb.c:32
        #37 0x7f16e1434f89 in __libc_start_main (/lib64/libc.so.6+0x20f89)
        #38 0x87bb49 in _start (build/gdb/gdb+0x87bb49)

    0x62500098c93c is located 0 bytes to the right of 8252-byte region \
      [0x62500098a900,0x62500098c93c)
    allocated by thread T0 here:
        #0 0x7f16e359a600 in malloc (/usr/lib64/libasan.so.5+0xeb600)
        #1 0x1742ddf in bfd_malloc src/bfd/libbfd.c:275
        #2 0x1738824 in bfd_get_full_section_contents src/bfd/compress.c:253
        #3 0xe30044 in gdb_bfd_map_section(bfd_section*, unsigned long*) \
                       src/gdb/gdb_bfd.c:704
        #4 0xcb56bf in dwarf2_read_section(objfile*, dwarf2_section_info*) \
                       src/gdb/dwarf2read.c:2539
        #5 0xd5bcd0 in get_gdb_index_contents_from_section<dwarf2_per_objfile>
\
                       src/gdb/dwarf2read.c:6217
        #6 0xd7fc7d in gdb::function_view<gdb::array_view<unsigned char const>
\
                       (...) const src/gdb/common/function-view.h:284
        #7 0xd7fddd in gdb::function_view<gdb::array_view<unsigned char const>
\
                       (...) src/gdb/common/function-view.h:278
        #8 0xd730cf in gdb::function_view<gdb::array_view<unsigned char const>
\
                       (...) const src/gdb/common/function-view.h:247
        #9 0xcbc7ee in dwarf2_read_gdb_index src/gdb/dwarf2read.c:3582
        #10 0xcce731 in dwarf2_initialize_objfile(objfile*, dw_index_kind*) \
                        src/gdb/dwarf2read.c:6297
        #11 0xdb88c4 in elf_symfile_read src/gdb/elfread.c:1256
        #12 0x141262a in read_symbols src/gdb/symfile.c:798
        #13 0x14140a7 in syms_from_objfile_1 src/gdb/symfile.c:1000
        #14 0x1414393 in syms_from_objfile src/gdb/symfile.c:1017
        #15 0x1414fb7 in symbol_file_add_with_addrs src/gdb/symfile.c:1124
        #16 0x14159b7 in symbol_file_add_from_bfd(bfd*, char const*, \
                         enum_flags<symfile_add_flag>,
std::vector<other_sections, \
                     std::allocator<other_sections> >*, \
                     enum_flags<objfile_flag>, objfile*) src/gdb/symfile.c:1203
        #17 0x1415b6c in symbol_file_add(char const*,
                         enum_flags<symfile_add_flag>,
std::vector<other_sections, \
                     std::allocator<other_sections> >*, \
                     enum_flags<objfile_flag>) src/gdb/symfile.c:1216
        #18 0x1415f2f in symbol_file_add_main_1 src/gdb/symfile.c:1240
        #19 0x1418599 in symbol_file_command(char const*, int) \
                         src/gdb/symfile.c:1675
        #20 0xde2fa6 in file_command src/gdb/exec.c:433
        #21 0xac96aa in do_const_cfunc src/gdb/cli/cli-decode.c:106
        #22 0xad0e5a in cmd_func(cmd_list_element*, char const*, int) \
                        src/gdb/cli/cli-decode.c:1892
        #23 0x15226f6 in execute_command(char const*, int) src/gdb/top.c:630
        #24 0xddde37 in command_handler(char const*) src/gdb/event-top.c:586
        #25 0xdde7c1 in command_line_handler(std::unique_ptr<char, \
                        gdb::xfree_deleter<char> >&&) src/gdb/event-top.c:773
        #26 0xddc9e8 in gdb_rl_callback_handler src/gdb/event-top.c:217
        #27 0x16f2198 in rl_callback_read_char src/readline/callback.c:220
        #28 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept \
                        src/gdb/event-top.c:175
        #29 0xddc773 in gdb_rl_callback_read_char_wrapper
src/gdb/event-top.c:192

    SUMMARY: AddressSanitizer: heap-buffer-overflow src/gdb/cp-support.c:999 in
\
      cp_find_first_component_aux
    Shadow bytes around the buggy address:
      0x0c4a801298d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c4a801298e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c4a801298f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c4a80129900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c4a80129910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    =>0x0c4a80129920: 00 00 00 00 00 00 00[04]fa fa fa fa fa fa fa fa
      0x0c4a80129930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a80129940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a80129950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a80129960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a80129970: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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
    ==31229==ABORTING
    ...

    The problem happens as follows.

    The executable amd64-init-x87-values gets an index (due to target board
    cc-with-gdb-index), which looks as follows:
    ...
    Hex dump of section '.gdb_index':
      0x00000000 08000000 18000000 28000000 28000000 ........(...(...
      0x00000010 3c000000 3c200000 00000000 00000000 <...< ..........
      0x00000020 2e000000 00000000 d4004000 00000000 ..........@.....
      0x00000030 db004000 00000000 00000000 00000000 ..@.............
      0x00000040 00000000 00000000 00000000 00000000 ................
      0x00000050 00000000 00000000 00000000 00000000 ................
      ... more zeroes ...
      0x00002010 00000000 00000000 00000000 00000000 ................
      0x00002020 00000000 00000000 00000000 00000000 ................
      0x00002030 00000000 00000000 00000000          ............
    ...

    The structure of this index is:
    ...
    header       : [0x0, 0x18)     : size 0x18
    culist       : [0x18 ,0x28)    : size 0x10
    typesculist  : [0x28, 0x28)    : size 0x0
    adress area  : [0x28, 0x3c)    : size 0x14
    symbol table : [0x3c, 0x203c)  : size 0x2000
    constant pool: [0x203c, 0x203c): size 0x0
    EOF          : 0x203c
    ...

    Note that the symbol table consists entirely of empty slots (where an empty
    slot is a pair of 32-bit zeroes), and that the constant pool is empty.

    The problem happens here in mapped_index_base::build_name_components:
    ...
      auto count = this->symbol_name_count ();
      for (offset_type idx = 0; idx < count; idx++)
        {
          if (this->symbol_name_slot_invalid (idx))
        continue;

          const char *name = this->symbol_name_at (idx);
    ...
    when accessing the slot at idx == 0 in the symbol table,
    symbol_name_slot_invalid returns false so we calculate name, which is
    calculated using 'constant_pool + symbol_table[idx].name', which means we
get
    name == constant_pool.  And given that the constant pool is empty, name now
    points past the memory allocated for the index, and when we access name[0]
for
    the first time in cp_find_first_component_aux, we run into the
    heap-buffer-overflow.

    Fix this by fixing the definition of symbol_name_slot_invalid:
    ...
    -    return bucket.name == 0 && bucket.vec;
    +    return bucket.name == 0 && bucket.vec == 0;
    ...

    Tested on x86_64-linux.

    gdb/ChangeLog:

    2019-06-10  Tom de Vries  <[hidden email]>

        PR gdb/24618
        * dwarf2read.c (struct mapped_index::symbol_name_slot_invalid): Make
        sure an empty slot (defined by a 32-bit zero pair) is recognized as
        invalid.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/24618] heap-buffer-overflow in cp_find_first_component_aux

adhemerval.zanella at linaro dot org
In reply to this post by adhemerval.zanella at linaro dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24618

Tom de Vries <vries at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from Tom de Vries <vries at gcc dot gnu.org> ---
Patch committed, marking resolved-fixed.

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