Bug 30639 - AddressSanitizer: dynamic-stack-buffer-overflow /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/ada-lang.c:1388:16 in ada_decode[abi:cxx11](char const*, bool, bool)
Summary: AddressSanitizer: dynamic-stack-buffer-overflow /home/root/sp/Dataset/Binutil...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: ada (show other bugs)
Version: 13.1
: P2 normal
Target Milestone: 14.1
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-07-15 06:26 UTC by 熊吉思汗
Modified: 2023-08-16 19:11 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-08-15 00:00:00


Attachments
crash seed (554 bytes, model/x.stl-binary)
2023-07-15 06:26 UTC, 熊吉思汗
Details
input file of -x option (128 bytes, text/plain)
2023-07-15 06:27 UTC, 熊吉思汗
Details
UAF_2 (540 bytes, model/x.stl-binary)
2023-07-29 05:49 UTC, 熊吉思汗
Details
command.gdb (128 bytes, text/plain)
2023-07-29 05:49 UTC, 熊吉思汗
Details

Note You need to log in before you can comment on or make changes to this bug.
Description 熊吉思汗 2023-07-15 06:26:30 UTC
Created attachment 14967 [details]
crash seed

Hello GDB developers,
We recently conducted a fuzzing test on GDB and discovered a dynamic-stack-buffer-overflow bug. We would like to provide a detailed description of the bug and seek your assistance in addressing it.

version:
gdb:GNU gdb (GDB) 13.0.50.20220805-git
gcc:gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
ubuntu: 20.04

command to reproduce:
gdb -x command.gdb UAF_2
UAF_2 is attached to this report.
command.gdb is attached to the first comment.


ASAN report:
=================================================================
==2661699==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffe5c3013ff at pc 0x00000057b9bd bp 0x7ffe5c300910 sp 0x7ffe5c300908
READ of size 1 at 0x7ffe5c3013ff thread T0
    #0 0x57b9bc in ada_decode[abi:cxx11](char const*, bool, bool) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/ada-lang.c:1388:16
    #1 0x61bbd1 in ada_language::sniff_from_mangled_name(char const*, std::unique_ptr<char, gdb::xfree_deleter<char> >*) const /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/ada-lang.c:13574:29
    #2 0x1c46d7d in symbol_find_demangled_name(general_symbol_info*, char const*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symtab.c:892:17
    #3 0x1c47e70 in general_symbol_info::compute_and_set_names(gdb::basic_string_view<char, std::char_traits<char> >, bool, objfile_per_bfd_storage*, gdb::optional<unsigned int>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symtab.c:980:7
    #4 0xb2919d in process_coff_symbol(coff_symbol*, internal_auxent*, objfile*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/coffread.c:1571:8
    #5 0xb2604b in coff_symtab_read(minimal_symbol_reader&, long, unsigned int, objfile*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/coffread.c:1183:4
    #6 0xb1d5ea in coff_read_minsyms(long, unsigned int, objfile*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/coffread.c:554:7
    #7 0xb1abd0 in coff_symfile_read(objfile*, enum_flags<symfile_add_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/coffread.c:702:3
    #8 0x1bf6a0e in read_symbols(objfile*, enum_flags<symfile_add_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:772:3
    #9 0x1c19531 in syms_from_objfile_1(objfile*, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<symfile_add_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:968:3
    #10 0x1c180fd in syms_from_objfile(objfile*, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<symfile_add_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:985:3
    #11 0x1be663c in symbol_file_add_with_addrs(bfd*, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:1088:3
    #12 0x1be70b3 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*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:1168:10
    #13 0x1be7459 in symbol_file_add(char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:1181:10
    #14 0x1be873e in symbol_file_add_main_1(char const*, enum_flags<symfile_add_flag>, enum_flags<objfile_flag>, unsigned long) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:1205:29
    #15 0x1be82ea in symbol_file_add_main(char const*, enum_flags<symfile_add_flag>) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symfile.c:1196:3
    #16 0x15c8b73 in symbol_file_add_main_adapter(char const*, int) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/main.c:540:3
    #17 0x15c6d2c in catch_command_errors(void (*)(char const*, int), char const*, int, bool) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/main.c:513:7
    #18 0x15c433a in captured_main_1(captured_main_args*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/main.c:1212:8
    #19 0x15be28d in captured_main(void*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/main.c:1319:3
    #20 0x15be058 in gdb_main(captured_main_args*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/main.c:1344:7
    #21 0x4e4f12 in main /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/gdb.c:32:10
    #22 0x7f63cb655082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #23 0x433ebd in _start (/home/root/sp/Fuzz/aflpp_fuzz/Binutils/document_group/batch_x/gdb_1/gdb+0x433ebd)

Address 0x7ffe5c3013ff is located in stack of thread T0 at offset 479 in frame
    #0 0x1c4685f in symbol_find_demangled_name(general_symbol_info*, char const*) /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/symtab.c:872

  This frame has 1 object(s):
    [32, 40) 'demangled' (line 873) <== Memory access at offset 479 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow /home/root/sp/Dataset/Binutils/binutils_aflpp/gdb/ada-lang.c:1388:16 in ada_decode[abi:cxx11](char const*, bool, bool)
Shadow bytes around the buggy address:
  0x10004b858220: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004b858230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004b858240: 00 00 00 00 f1 f1 f1 f1 00 f3 f3 f3 00 00 00 00
  0x10004b858250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004b858260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10004b858270: 00 00 00 00 00 00 00 00 00 00 00 00 ca ca ca[ca]
  0x10004b858280: 03 cb cb cb cb cb cb cb f1 f1 f1 f1 00 00 f2 f2
  0x10004b858290: 00 00 00 00 f2 f2 f2 f2 00 00 f2 f2 f8 f2 00 f2
  0x10004b8582a0: f2 f2 00 00 f2 f2 f8 f8 f2 f2 00 f2 f2 f2 00 00
  0x10004b8582b0: f2 f2 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
  0x10004b8582c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==2661699==ABORTING

Thank you for your attention and support.
Best regards,
Michael Zhang.
Comment 1 熊吉思汗 2023-07-15 06:27:04 UTC
Created attachment 14968 [details]
input file of -x option

input file of -x option
Comment 2 Keith Seitz 2023-07-26 19:15:09 UTC
The supplied executable does not segfault gdb in the reported location:

$ ./gdb -nx -q --data-directory data-directory UAF_2
Reading symbols from UAF_2...


Fatal signal: Segmentation fault
----- Backtrace -----
0x599064 gdb_internal_backtrace_1
	../../src/gdb/bt-utils.c:122
0x599107 _Z22gdb_internal_backtracev
	../../src/gdb/bt-utils.c:168
0x782fd4 handle_fatal_signal
	../../src/gdb/event-top.c:889
0x783140 handle_sigsegv
	../../src/gdb/event-top.c:962
0x7fe5a7d7eb6f ???
0x6107a5 process_coff_symbol
	../../src/gdb/coffread.c:1572
0x60f847 coff_symtab_read
	../../src/gdb/coffread.c:1190
0x60e0dd coff_read_minsyms
	../../src/gdb/coffread.c:549
0x60e629 coff_symfile_read
	../../src/gdb/coffread.c:698
0xbd975e read_symbols
	../../src/gdb/symfile.c:772
0xbd9e0b syms_from_objfile_1
	../../src/gdb/symfile.c:966
0xbd9ecf syms_from_objfile
	../../src/gdb/symfile.c:983
0xbda3aa symbol_file_add_with_addrs
	../../src/gdb/symfile.c:1086
0xbda6eb _Z24symbol_file_add_from_bfdRKN3gdb7ref_ptrI3bfd18gdb_bfd_ref_policyEEPKc10enum_flagsI16symfile_add_flagEPSt6vectorI14other_sectionsSaISC_EES8_I12objfile_flagEP7objfile
	../../src/gdb/symfile.c:1166
0xbda73a _Z15symbol_file_addPKc10enum_flagsI16symfile_add_flagEPSt6vectorI14other_sectionsSaIS5_EES1_I12objfile_flagE
	../../src/gdb/symfile.c:1179
0xbda7ff symbol_file_add_main_1
	../../src/gdb/symfile.c:1203
0xbda7a6 _Z20symbol_file_add_mainPKc10enum_flagsI16symfile_add_flagE
	../../src/gdb/symfile.c:1194
0x90b1d7 symbol_file_add_main_adapter
	../../src/gdb/main.c:549
0x90b0ed catch_command_errors
	../../src/gdb/main.c:518
0x90c20e captured_main_1
	../../src/gdb/main.c:1203
0x90c820 captured_main
	../../src/gdb/main.c:1310
0x90c8bf _Z8gdb_mainP18captured_main_args
	../../src/gdb/main.c:1339
0x418c3c main
	../../src/gdb/gdb.c:32
---------------------
A fatal error internal to GDB has been detected, further
debugging is not possible.  GDB will now terminate.

This is a bug, please report it.  For instructions, see:
<https://www.gnu.org/software/gdb/bugs/>.

Segmentation fault (core dumped)

Did you attach the correct binary to this bug?
Comment 3 熊吉思汗 2023-07-29 05:35:10 UTC
(In reply to Keith Seitz from comment #2)
> The supplied executable does not segfault gdb in the reported location:
> 
> $ ./gdb -nx -q --data-directory data-directory UAF_2
> Reading symbols from UAF_2...
> 
> 
> Fatal signal: Segmentation fault
> ----- Backtrace -----
> 0x599064 gdb_internal_backtrace_1
> 	../../src/gdb/bt-utils.c:122
> 0x599107 _Z22gdb_internal_backtracev
> 	../../src/gdb/bt-utils.c:168
> 0x782fd4 handle_fatal_signal
> 	../../src/gdb/event-top.c:889
> 0x783140 handle_sigsegv
> 	../../src/gdb/event-top.c:962
> 0x7fe5a7d7eb6f ???
> 0x6107a5 process_coff_symbol
> 	../../src/gdb/coffread.c:1572
> 0x60f847 coff_symtab_read
> 	../../src/gdb/coffread.c:1190
> 0x60e0dd coff_read_minsyms
> 	../../src/gdb/coffread.c:549
> 0x60e629 coff_symfile_read
> 	../../src/gdb/coffread.c:698
> 0xbd975e read_symbols
> 	../../src/gdb/symfile.c:772
> 0xbd9e0b syms_from_objfile_1
> 	../../src/gdb/symfile.c:966
> 0xbd9ecf syms_from_objfile
> 	../../src/gdb/symfile.c:983
> 0xbda3aa symbol_file_add_with_addrs
> 	../../src/gdb/symfile.c:1086
> 0xbda6eb
> _Z24symbol_file_add_from_bfdRKN3gdb7ref_ptrI3bfd18gdb_bfd_ref_policyEEPKc10en
> um_flagsI16symfile_add_flagEPSt6vectorI14other_sectionsSaISC_EES8_I12objfile_
> flagEP7objfile
> 	../../src/gdb/symfile.c:1166
> 0xbda73a
> _Z15symbol_file_addPKc10enum_flagsI16symfile_add_flagEPSt6vectorI14other_sect
> ionsSaIS5_EES1_I12objfile_flagE
> 	../../src/gdb/symfile.c:1179
> 0xbda7ff symbol_file_add_main_1
> 	../../src/gdb/symfile.c:1203
> 0xbda7a6 _Z20symbol_file_add_mainPKc10enum_flagsI16symfile_add_flagE
> 	../../src/gdb/symfile.c:1194
> 0x90b1d7 symbol_file_add_main_adapter
> 	../../src/gdb/main.c:549
> 0x90b0ed catch_command_errors
> 	../../src/gdb/main.c:518
> 0x90c20e captured_main_1
> 	../../src/gdb/main.c:1203
> 0x90c820 captured_main
> 	../../src/gdb/main.c:1310
> 0x90c8bf _Z8gdb_mainP18captured_main_args
> 	../../src/gdb/main.c:1339
> 0x418c3c main
> 	../../src/gdb/gdb.c:32
> ---------------------
> A fatal error internal to GDB has been detected, further
> debugging is not possible.  GDB will now terminate.
> 
> This is a bug, please report it.  For instructions, see:
> <https://www.gnu.org/software/gdb/bugs/>.
> 
> Segmentation fault (core dumped)
> 
> Did you attach the correct binary to this bug?

To reproduce this bug, please use the following command: gdb -x command.gdb UAF_2. The necessary files for this command are as follows: command.gdb (attachment_14968) and UAF_2 (attachment_14967). You can find command.gdb attached to the first comment, and UAF_2 attached as attachment_14967. If you encounter any issues during the reproduction process, please feel free to let me know.
Comment 4 熊吉思汗 2023-07-29 05:49:06 UTC
Created attachment 15019 [details]
UAF_2
Comment 5 熊吉思汗 2023-07-29 05:49:57 UTC
Created attachment 15020 [details]
command.gdb
Comment 6 熊吉思汗 2023-07-29 05:50:41 UTC
I uploaded the command.gdb and UAF_2 file in the comment below.
Comment 7 Tom Tromey 2023-07-29 15:15:58 UTC
For me this crashes in read_pe_truncate_name because
read_pe_exported_syms seems to make a pointer to invalid memory.
If there's a crash in the Ada decoder, that isn't a case of GIGO,
what I'd really like to know is the name being decoded.
Comment 8 Keith Seitz 2023-08-15 18:11:34 UTC
My apologies, this DOES reproduce (as Tom notes). The thing I
ignored was ASAN. [The crash I reported was recently fixed by
Alan Modra's "gdb: warn unused result for bfd IO functions".]

[Probably TMI for Tom, but for anyone following along...]

In process_coff_symbol, we are processing a symbol with name "44",
i.e, just digits. The language of this objfile is language_unknown.

process_coff_symbol calls general_symbol_info::compute_and_set_names.
This eventually calls symbol_find_demangled_name with linkage_name_copy
set to "44". Since the objfile's language is unknown, symbol_find_linkage_name
iterates over all languages, calling the language's sniff_from_mangled_name
method. This does nothing for all the languages until it hits language_ada.

ada_language::sniff_from_mangled immediately calls ada_decode.

The code here essentially skips to the last block which attempts to
remove trailing digits:

1370   /* Remove trailing __{digit}+ or trailing ${digit}+.  */
1371
1372   if (len0 > 1 && isdigit (encoded[len0 - 1]))
1373     {
1374       i = len0 - 2;
1375       while ((i >= 0 && isdigit (encoded[i]))
1376              || (i >= 1 && encoded[i] == '_' && isdigit (encoded[i - 1])))
1377         i -= 1;
1378       if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_')
1379         len0 = i - 1;
1380       else if (encoded[i] == '$')
1381         len0 = i;
1382     }

When we get to 1372, len0 is strlen("44") which is 2. encoded[2 - 1] = "4" is
a digit, and we set i = len0 - 2 = 0.

Now the while loop: i == 0 and encoded[0] is "4", so that passes the first
test, and we subtract 1 from i, setting it to -1. Now i is no longer >= 0
or >= 1, so the while loop escapes. Finally, we hit the final "else if"
encoded[-1] == '$' on line 1380, which causes the observed buffer overflow.
Comment 9 Tom Tromey 2023-08-16 16:44:45 UTC
Thanks for the analysis, Keith.
I'll send a patch soon.
Comment 10 Sourceware Commits 2023-08-16 19:08:17 UTC
The master branch has been updated by Tom Tromey <tromey@sourceware.org>:

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

commit 033bc52bb6190393c8eed80925fa78cc35b40c6d
Author: Tom Tromey <tromey@adacore.com>
Date:   Wed Aug 16 11:29:19 2023 -0600

    Avoid buffer overflow in ada_decode
    
    A bug report pointed out a buffer overflow in ada_decode, which Keith
    helpfully analyzed.  ada_decode had a logic error when the input was
    all digits.  While this isn't valid -- and would probably only appear
    in fuzzer tests -- it still should be handled properly.
    
    This patch adds a missing bounds check.  Tested with the self-tests in
    an asan build.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30639
    Reviewed-by: Keith Seitz <keiths@redhat.com>
Comment 11 Tom Tromey 2023-08-16 19:11:32 UTC
Fixed.