binutils-gdb/gdb/common
Tom de Vries 310b3441a0 [gdb] Fix heap-buffer-overflow in child_path
When compiling gdb with '-lasan -fsanitizer=address' and running tests with:
- export ASAN_OPTIONS="detect_leaks=0:alloc_dealloc_mismatch=0", and
- a target board using local-board.exp, which sets sysroot to ""
we run into a heap-buffer-overflow in child_path for f.i. gdb.arch/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*) \
                      gdb/common/pathstuff.c:161
    #1 0x5602adb06587 in find_separate_debug_file gdb/symfile.c:1483
    #2 0x5602adb06f2f in find_separate_debug_file_by_debuglink[abi:cxx11](...) \
                      gdb/symfile.c:1563
    #3 0x5602ad13b743 in elf_symfile_read gdb/elfread.c:1293
    #4 0x5602adb01cfa in read_symbols gdb/symfile.c:798
    #5 0x5602adb03769 in syms_from_objfile_1 gdb/symfile.c:1000
    #6 0x5602adb039d0 in syms_from_objfile gdb/symfile.c:1017
    #7 0x5602adb04551 in symbol_file_add_with_addrs gdb/symfile.c:1124
    #8 0x5602adb04ebf in symbol_file_add_from_bfd(...) gdb/symfile.c:1204
    #9 0x5602ada5a78d in solib_read_symbols(...) gdb/solib.c:695
    #10 0x5602ada5bdae in solib_add(char const*, int, int) gdb/solib.c:1004
    #11 0x5602ada49bcd in enable_break gdb/solib-svr4.c:2394
    #12 0x5602ada4dae9 in svr4_solib_create_inferior_hook gdb/solib-svr4.c:3028
    #13 0x5602ada5d4f1 in solib_create_inferior_hook(int) gdb/solib.c:1215
    #14 0x5602ad347f66 in post_create_inferior(target_ops*, int) \
                          gdb/infcmd.c:467
    #15 0x5602ad348b3c in run_command_1 gdb/infcmd.c:663
    #16 0x5602ad348e55 in run_command gdb/infcmd.c:686
    #17 0x5602acd7d32b in do_const_cfunc gdb/cli/cli-decode.c:106
    #18 0x5602acd84bfe in cmd_func(cmd_list_element*, char const*, int) \
                          gdb/cli/cli-decode.c:1892
    #19 0x5602adc62a90 in execute_command(char const*, int) gdb/top.c:630
    #20 0x5602ad5053e6 in catch_command_errors gdb/main.c:372
    #21 0x5602ad507eb1 in captured_main_1 gdb/main.c:1138
    #22 0x5602ad5081ec in captured_main gdb/main.c:1163
    #23 0x5602ad508281 in gdb_main(captured_main_args*) gdb/main.c:1188
    #24 0x5602ac9ddc3a in main 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 gdb/common/common-utils.c:44
    #2 0x5602aefe17d1 in xstrdup libiberty/xstrdup.c:34
    #3 0x5602acdf61f6 in gdb_realpath(char const*) gdb/common/pathstuff.c:80
    #4 0x5602adb06278 in find_separate_debug_file gdb/symfile.c:1444
    #5 0x5602adb06f2f in find_separate_debug_file_by_debuglink[abi:cxx11](...) \
                      gdb/symfile.c:1563
    #6 0x5602ad13b743 in elf_symfile_read gdb/elfread.c:1293
    #7 0x5602adb01cfa in read_symbols gdb/symfile.c:798
    #8 0x5602adb03769 in syms_from_objfile_1 gdb/symfile.c:1000
    #9 0x5602adb039d0 in syms_from_objfile gdb/symfile.c:1017
    #10 0x5602adb04551 in symbol_file_add_with_addrs gdb/symfile.c:1124
    #11 0x5602adb04ebf in symbol_file_add_from_bfd(...) gdb/solib.c:695
    #13 0x5602ada5bdae in solib_add(char const*, int, int) gdb/solib.c:1004
    #14 0x5602ada49bcd in enable_break gdb/solib-svr4.c:2394
    #15 0x5602ada4dae9 in svr4_solib_create_inferior_hook gdb/solib-svr4.c:3028
    #16 0x5602ada5d4f1 in solib_create_inferior_hook(int) gdb/solib.c:1215
    #17 0x5602ad347f66 in post_create_inferior(target_ops*, int) \
                       gdb/infcmd.c:467
    #18 0x5602ad348b3c in run_command_1 gdb/infcmd.c:663
    #19 0x5602ad348e55 in run_command gdb/infcmd.c:686
    #20 0x5602acd7d32b in do_const_cfunc gdb/cli/cli-decode.c:106
    #21 0x5602acd84bfe in cmd_func(cmd_list_element*, char const*, int) \
                       gdb/cli/cli-decode.c:1892
    #22 0x5602adc62a90 in execute_command(char const*, int) gdb/top.c:630
    #23 0x5602ad5053e6 in catch_command_errors gdb/main.c:372
    #24 0x5602ad507eb1 in captured_main_1 gdb/main.c:1138
    #25 0x5602ad5081ec in captured_main gdb/main.c:1163
    #26 0x5602ad508281 in gdb_main(captured_main_args*) gdb/main.c:1188
    #27 0x5602ac9ddc3a in main gdb/gdb.c:32
    #28 0x7f582b56eb96 in __libc_start_main \
                       (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow 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
...

The direct cause is that child_path gets called with parent == "", so this
test:
...
  if (IS_DIR_SEPARATOR (parent[parent_len - 1]))
...
accesses parent[-1].

[ There is an open discussion (1) about whether an empty sysroot should indeed
be represented internally as "".  But this patch focuses on fixing the
heap-buffer-overflow without any redesign. ]

Fix this by guarding the test with 'parent_len > 0'.

Note that the fix makes child_path behave the same for:
- parent == "/" && child == "/foo" (returns "foo")
- parent == "" and child == "/foo" (returns "foo").

Build and reg-tested on x86_64-linux.

(1) https://sourceware.org/ml/gdb-patches/2019-05/msg00193.html

gdb/ChangeLog:

2019-06-17  Tom de Vries  <tdevries@suse.de>

	PR gdb/24617
	* common/pathstuff.c (child_path): Make sure parent_len > 0 before
	accessing parent[parent_len - 1].
2019-06-17 22:25:06 +02:00
..
agent.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
agent.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
array-view.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
ax.def Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
break-common.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
btrace-common.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
btrace-common.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
buffer.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
buffer.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
byte-vector.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
cleanups.c Remove basic cleanup code 2019-03-06 16:04:31 -07:00
cleanups.h Remove basic cleanup code 2019-03-06 16:04:31 -07:00
common-debug.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
common-debug.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common-defs.h Move gnulib to top level 2019-06-14 12:40:02 -06:00
common-exceptions.c Make exception handling more efficient 2019-04-25 12:59:35 -06:00
common-exceptions.h Make exception handling more efficient 2019-04-25 12:59:35 -06:00
common-gdbthread.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common-inferior.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common-regcache.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
common-regcache.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common-types.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common-utils.c Move gdb's xmalloc and friends to new file 2019-06-11 07:41:00 -06:00
common-utils.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
common.host Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
common.m4 Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
create-version.sh Update create-version.sh to use common/version.h 2019-01-25 15:28:16 -07:00
def-vector.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
default-init-alloc.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
enum-flags.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
environ.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
environ.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
errors.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
errors.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
fileio.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
fileio.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
filestuff.c Introduce and use make_unique_xstrdup 2019-06-04 22:48:32 +01:00
filestuff.h Remove last cleanup from linux-namespaces.c 2019-03-06 16:04:31 -07:00
filtered-iterator.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
format.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
format.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
forward-scope-exit.h Fix clang/libc++ build 2019-01-24 18:01:49 +00:00
function-view.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
gdb_assert.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_locale.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_optional.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_proc_service.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
gdb_ref_ptr.h Add ATTRIBUTE_UNUSED_RESULT to ref_ptr::release 2019-03-05 08:48:40 -07:00
gdb_setjmp.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_signals.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
gdb_splay_tree.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_string_view.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_string_view.tcc Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
gdb_sys_time.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_tilde_expand.c Introduce and use make_unique_xstrdup 2019-06-04 22:48:32 +01:00
gdb_tilde_expand.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_unique_ptr.h Introduce and use make_unique_xstrdup 2019-06-04 22:48:32 +01:00
gdb_unlinker.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_vecs.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
gdb_vecs.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
gdb_wait.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
hash_enum.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
host-defs.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
job-control.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
job-control.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
mingw-strerror.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
netstuff.c On MS-Windows, define _WIN32_WINNT in a single common place. 2019-05-03 10:55:33 +03:00
netstuff.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
new-op.c Make exception handling more efficient 2019-04-25 12:59:35 -06:00
next-iterator.h Remove ALL_OBJFILES_SAFE 2019-01-09 18:28:14 -07:00
observable.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
offset-type.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
pathstuff.c [gdb] Fix heap-buffer-overflow in child_path 2019-06-17 22:25:06 +02:00
pathstuff.h Add a new function child_path. 2019-02-12 13:56:16 -08:00
poison.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
posix-strerror.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
preprocessor.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
print-utils.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
print-utils.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
ptid.c Make null_ptid and minus_one_ptid "const" 2019-03-12 10:45:37 -06:00
ptid.h Make null_ptid and minus_one_ptid "const" 2019-03-12 10:45:37 -06:00
refcounted-object.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
rsp-low.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
rsp-low.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
run-time-clock.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
run-time-clock.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
safe-iterator.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
scope-exit.h Introduce scope_exit 2019-01-23 19:02:58 +00:00
scoped_fd.h Add ATTRIBUTE_UNUSED_RESULT to scoped_fd 2019-03-05 08:48:40 -07:00
scoped_mmap.c Fix scoped_mmap includes 2019-05-06 21:00:52 -06:00
scoped_mmap.h Fix scoped_mmap includes 2019-05-06 21:00:52 -06:00
scoped_restore.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
selftest.c Rename gdb exception types 2019-04-08 09:05:40 -06:00
selftest.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
signals-state-save-restore.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
signals-state-save-restore.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
signals.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
symbol.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
tdesc.c AArch64: Add half float view to V registers 2019-05-14 10:10:56 +01:00
tdesc.h AArch64: Add half float view to V registers 2019-05-14 10:10:56 +01:00
traits.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
underlying.h Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
valid-expr.h Rename ESC -> ESC_PARENS 2019-01-23 18:58:28 +00:00
vec.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
vec.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
version.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
x86-xstate.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
xml-utils.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
xml-utils.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00