[PATCH][gdb/testsuite] Fix break-probes.exp with native-gdbserver

Tom de Vries tdevries@suse.de
Fri May 24 07:50:00 GMT 2019


[ To make sure we don't loose track of this, filed as PR24617 -
"heap-buffer-overflow in child_path" (
https://sourceware.org/bugzilla/show_bug.cgi?id=24617 ). ]

On 08-05-19 04:09, Simon Marchi wrote:
> On 2019-04-18 5:42 p.m., Tom de Vries wrote:
>> On 18-04-19 20:13, Pedro Alves wrote:
>>> On 4/18/19 5:50 PM, Tom de Vries wrote:
>>>> Hi,
>>>>
>>>> When running break-probes.exp with native-gdbserver, we run into:
>>>> ...
>>>> FAIL: gdb.base/break-probes.exp: run til our library loads (the program exited)
>>>> FAIL: gdb.base/break-probes.exp: call (int) foo(23)
>>>> ...
>>>> due to the fact that we're trying to match:
>>>> ...
>>>> Inferior loaded /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base\
>>>>   /break-probes/break-probes-solib.so
>>>> ...
>>>> using pattern:
>>>> ...
>>>> Inferior loaded $sysroot$binfile_lib
>>>> ...
>>>> which expands into:
>>>> ...
>>>> Inferior loaded //data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base\
>>>>   /break-probes/break-probes-solib.so
>>>> ...
>>>>
>>>> Fix this by removing trailing slashes from the sysroot variable.
>>>>
>>>> Tested on x86_64-linux with native and native-gdbserver (with sysroot set to
>>>> "/", "/." and "/./").
>>>>
>>>> OK for trunk?
>>>>
>>>
>>> I think we made a little mistake in the recent "set sysroot in board file" patch:
>>>
>>> commit c92df149c29518f6e1d4a3174b3e29162fcd3ad6
>>> Author:     Alan Hayward <alan.hayward@arm.com>
>>> AuthorDate: Thu Mar 28 12:33:29 2019 +0000
>>>
>>>     Testsuite: set sysroot when using gdbserver
>>>
>>> I think it would be better to make that do
>>>
>>> "set sysroot"
>>>
>>> instead of the current
>>>
>>> "set sysroot /"
>>>
>>> Setting the sysroot to empty means to read from the local filesystem,
>>> which is what was intended.
>>>
>>> And with that, this patch shouldn't be necessary.
>>
>> Ack, committed as below.
>>
>> Thanks,
>> - Tom
>>
> 
> Sorry, I am bringing some bad news.  On my Ubuntu 18.04, I see sone ASan failure, not caused
> by this patch but exposed by it.  See below for detailed backtrace.
> 
> The sequence of events is
> 
> - "set sysroot" sets gdb_sysroot to the empty string.
> - This call to gdb_realpath in find_separate_debug_file returns an empty string as well
> 
>     gdb::unique_xmalloc_ptr<char> canon_sysroot = gdb_realpath (gdb_sysroot);
> 
> - This call call to child_path:
> 
>     child_path (canon_sysroot.get (), canon_dir);
> 
>   then accesses the byte just before canon_sysroot when it does:
> 
>     parent[parent_len - 1]
> 
> 
> It's not clear to me who is at fault here, it could be many things.
> 
> 1. Should we allow passing an empty string to gdb_realpath, or assert in gdb_realpath that the
>    input isn't the empty string?
> 2. If we allow it, what should gdb_realpath return?  Currently it returns the empty string as
>    well, is it right or should it return NULL?
> 3. Should child_path allow any of its inputs to be an empty string, or should it assert that
>    they aren't?
> 4. If we allow them to be empty strings, what should it return?
> 5. find_separate_debug_file should probably check whether we are using a sysroot in the first
>    place.
> 
> Also, currently, we represent "no sysroot" by having gdb_sysroot point to an empty string.  This
> ensures that gdb_sysroot is never NULL, and I think that many parts of GDB assume that.  Should
> we change it so that gdb_sysroot is NULL when we are not using a sysroot (and adjust the relevant
> parts of GDB)?  Currently, some places use the check "*gdb_sysroot != '\0'" to determine whether
> we are using a sysroot.  This works, but there is the risks of bugs like this one, where some code
> uses the empty string sysroot value and tries to do stuff with it, even though it's not really
> a valid sysroot value (nor a valid path value).  If gdb_sysroot was NULL to denote "no sysroot",
> the check to find out whether we're using a sysroot would become "gdb_sysroot != NULL".  It would
> be much harder to forget it, because it would most likely result in a crash.
> 
> Simon
> 
> $ ./gdb testsuite/outputs/gdb.arch/amd64-byte/amd64-byte -ex "b main" -ex "set sysroot" -ex r
> Exception caught while booting Guile.
> Error in function "open-file":
> No such file or directory: "/usr/local/share/gdb/guile/gdb/boot.scm"
> ./gdb: warning: Could not complete Guile gdb module initialization from:
> /usr/local/share/gdb/guile/gdb/boot.scm.
> Limited Guile support is available.
> Suggest passing --data-directory=/path/to/gdb/data-directory.
> 
> Python Exception <class 'ModuleNotFoundError'> No module named 'gdb':
> ./gdb: warning:
> Could not load the Python gdb module from `/usr/local/share/gdb/python'.
> Limited Python support is available from the _gdb module.
> Suggest passing --data-directory=/path/to/gdb/data-directory.
> 
> GNU gdb (GDB) 8.3.50.20190507-git
> Copyright (C) 2019 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.
> Type "show copying" and "show warranty" for details.
> This GDB was configured as "x86_64-pc-linux-gnu".
> Type "show configuration" for configuration details.
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Find the GDB manual and other documentation resources online at:
>     <http://www.gnu.org/software/gdb/documentation/>.
> 
> For help, type "help".
> Type "apropos word" to search for commands related to "word"...
> Reading symbols from testsuite/outputs/gdb.arch/amd64-byte/amd64-byte...
> Breakpoint 1 at 0x652: file /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo.c, line 57.
> Starting program: /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.arch/amd64-byte/amd64-byte
> =================================================================
> ==3997==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200002abcf at pc 0x5602acdf6872 bp 0x7ffe5237a090 sp 0x7ffe5237a080
> READ of size 1 at 0x60200002abcf thread T0
>     #0 0x5602acdf6871 in child_path(char const*, char const*) /home/smarchi/src/binutils-gdb/gdb/common/pathstuff.c:161
>     #1 0x5602adb06587 in find_separate_debug_file /home/smarchi/src/binutils-gdb/gdb/symfile.c:1483
>     #2 0x5602adb06f2f in find_separate_debug_file_by_debuglink[abi:cxx11](objfile*) /home/smarchi/src/binutils-gdb/gdb/symfile.c:1563
>     #3 0x5602ad13b743 in elf_symfile_read /home/smarchi/src/binutils-gdb/gdb/elfread.c:1293
>     #4 0x5602adb01cfa in read_symbols /home/smarchi/src/binutils-gdb/gdb/symfile.c:798
>     #5 0x5602adb03769 in syms_from_objfile_1 /home/smarchi/src/binutils-gdb/gdb/symfile.c:1000
>     #6 0x5602adb039d0 in syms_from_objfile /home/smarchi/src/binutils-gdb/gdb/symfile.c:1017
>     #7 0x5602adb04551 in symbol_file_add_with_addrs /home/smarchi/src/binutils-gdb/gdb/symfile.c:1124
>     #8 0x5602adb04ebf in symbol_file_add_from_bfd(bfd*, char const*, enum_flags<symfile_add_flag>, std::__debug::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) /home/smarchi/src/binutils-gdb/gdb/symfile.c:1204
>     #9 0x5602ada5a78d in solib_read_symbols(so_list*, enum_flags<symfile_add_flag>) /home/smarchi/src/binutils-gdb/gdb/solib.c:695
>     #10 0x5602ada5bdae in solib_add(char const*, int, int) /home/smarchi/src/binutils-gdb/gdb/solib.c:1004
>     #11 0x5602ada49bcd in enable_break /home/smarchi/src/binutils-gdb/gdb/solib-svr4.c:2394
>     #12 0x5602ada4dae9 in svr4_solib_create_inferior_hook /home/smarchi/src/binutils-gdb/gdb/solib-svr4.c:3028
>     #13 0x5602ada5d4f1 in solib_create_inferior_hook(int) /home/smarchi/src/binutils-gdb/gdb/solib.c:1215
>     #14 0x5602ad347f66 in post_create_inferior(target_ops*, int) /home/smarchi/src/binutils-gdb/gdb/infcmd.c:467
>     #15 0x5602ad348b3c in run_command_1 /home/smarchi/src/binutils-gdb/gdb/infcmd.c:663
>     #16 0x5602ad348e55 in run_command /home/smarchi/src/binutils-gdb/gdb/infcmd.c:686
>     #17 0x5602acd7d32b in do_const_cfunc /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:106
>     #18 0x5602acd84bfe in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:1892
>     #19 0x5602adc62a90 in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:630
>     #20 0x5602ad5053e6 in catch_command_errors /home/smarchi/src/binutils-gdb/gdb/main.c:372
>     #21 0x5602ad507eb1 in captured_main_1 /home/smarchi/src/binutils-gdb/gdb/main.c:1138
>     #22 0x5602ad5081ec in captured_main /home/smarchi/src/binutils-gdb/gdb/main.c:1163
>     #23 0x5602ad508281 in gdb_main(captured_main_args*) /home/smarchi/src/binutils-gdb/gdb/main.c:1188
>     #24 0x5602ac9ddc3a in main /home/smarchi/src/binutils-gdb/gdb/gdb.c:32
>     #25 0x7f582b56eb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
>     #26 0x5602ac9dda09 in _start (/home/smarchi/build/binutils-gdb/gdb/gdb+0x19a2a09)
> 
> 0x60200002abcf is located 1 bytes to the left of 1-byte region [0x60200002abd0,0x60200002abd1)
> allocated by thread T0 here:
>     #0 0x7f582e0e4b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
>     #1 0x5602acdd3656 in xmalloc /home/smarchi/src/binutils-gdb/gdb/common/common-utils.c:44
>     #2 0x5602aefe17d1 in xstrdup /home/smarchi/src/binutils-gdb/libiberty/xstrdup.c:34
>     #3 0x5602acdf61f6 in gdb_realpath(char const*) /home/smarchi/src/binutils-gdb/gdb/common/pathstuff.c:80
>     #4 0x5602adb06278 in find_separate_debug_file /home/smarchi/src/binutils-gdb/gdb/symfile.c:1444
>     #5 0x5602adb06f2f in find_separate_debug_file_by_debuglink[abi:cxx11](objfile*) /home/smarchi/src/binutils-gdb/gdb/symfile.c:1563
>     #6 0x5602ad13b743 in elf_symfile_read /home/smarchi/src/binutils-gdb/gdb/elfread.c:1293
>     #7 0x5602adb01cfa in read_symbols /home/smarchi/src/binutils-gdb/gdb/symfile.c:798
>     #8 0x5602adb03769 in syms_from_objfile_1 /home/smarchi/src/binutils-gdb/gdb/symfile.c:1000
>     #9 0x5602adb039d0 in syms_from_objfile /home/smarchi/src/binutils-gdb/gdb/symfile.c:1017
>     #10 0x5602adb04551 in symbol_file_add_with_addrs /home/smarchi/src/binutils-gdb/gdb/symfile.c:1124
>     #11 0x5602adb04ebf in symbol_file_add_from_bfd(bfd*, char const*, enum_flags<symfile_add_flag>, std::__debug::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) /home/smarchi/src/binutils-gdb/gdb/symfile.c:1204
>     #12 0x5602ada5a78d in solib_read_symbols(so_list*, enum_flags<symfile_add_flag>) /home/smarchi/src/binutils-gdb/gdb/solib.c:695
>     #13 0x5602ada5bdae in solib_add(char const*, int, int) /home/smarchi/src/binutils-gdb/gdb/solib.c:1004
>     #14 0x5602ada49bcd in enable_break /home/smarchi/src/binutils-gdb/gdb/solib-svr4.c:2394
>     #15 0x5602ada4dae9 in svr4_solib_create_inferior_hook /home/smarchi/src/binutils-gdb/gdb/solib-svr4.c:3028
>     #16 0x5602ada5d4f1 in solib_create_inferior_hook(int) /home/smarchi/src/binutils-gdb/gdb/solib.c:1215
>     #17 0x5602ad347f66 in post_create_inferior(target_ops*, int) /home/smarchi/src/binutils-gdb/gdb/infcmd.c:467
>     #18 0x5602ad348b3c in run_command_1 /home/smarchi/src/binutils-gdb/gdb/infcmd.c:663
>     #19 0x5602ad348e55 in run_command /home/smarchi/src/binutils-gdb/gdb/infcmd.c:686
>     #20 0x5602acd7d32b in do_const_cfunc /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:106
>     #21 0x5602acd84bfe in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:1892
>     #22 0x5602adc62a90 in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:630
>     #23 0x5602ad5053e6 in catch_command_errors /home/smarchi/src/binutils-gdb/gdb/main.c:372
>     #24 0x5602ad507eb1 in captured_main_1 /home/smarchi/src/binutils-gdb/gdb/main.c:1138
>     #25 0x5602ad5081ec in captured_main /home/smarchi/src/binutils-gdb/gdb/main.c:1163
>     #26 0x5602ad508281 in gdb_main(captured_main_args*) /home/smarchi/src/binutils-gdb/gdb/main.c:1188
>     #27 0x5602ac9ddc3a in main /home/smarchi/src/binutils-gdb/gdb/gdb.c:32
>     #28 0x7f582b56eb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
> 
> SUMMARY: AddressSanitizer: heap-buffer-overflow /home/smarchi/src/binutils-gdb/gdb/common/pathstuff.c:161 in child_path(char const*, char const*)
> Shadow bytes around the buggy address:
>   0x0c047fffd520: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa
>   0x0c047fffd530: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
>   0x0c047fffd540: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
>   0x0c047fffd550: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa
>   0x0c047fffd560: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 00 00
> =>0x0c047fffd570: fa fa 07 fa fa fa 00 fa fa[fa]01 fa fa fa fa fa
>   0x0c047fffd580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffd590: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffd5a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffd5b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffd5c0: 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
> ==3997==ABORTING
> 



More information about the Gdb-patches mailing list