diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-11-09 13:02:12 +0100 |
---|---|---|
committer | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-11-09 13:02:12 +0100 |
commit | 0bb65f1e7c9eed7338ef2e4a2f5b42d010409c39 (patch) | |
tree | df300a6c6d78608fa6701239cb2465321b10fa46 | |
parent | 82b19a4d2f9c9e8d56fdffdd702f7db4af486386 (diff) | |
download | gdb-0bb65f1e7c9eed7338ef2e4a2f5b42d010409c39.zip gdb-0bb65f1e7c9eed7338ef2e4a2f5b42d010409c39.tar.gz gdb-0bb65f1e7c9eed7338ef2e4a2f5b42d010409c39.tar.bz2 |
tui-disasm: Fix window content buffer overrun
A user reported a GDB crash with TUI when trying to debug a function
with a long demangled C++ method name. It turned out that the logic for
displaying the TUI disassembly window has a bug that can cause a buffer
overrun, possibly overwriting GDB-internal data structures. In
particular, the logic performs an unguarded strcpy.
Another (harmless) bug in tui_alloc_source_buffer causes the buffer to
be two lines longer than needed. This may have made the crash appear
less frequently.
gdb/ChangeLog:
* tui/tui-disasm.c (tui_set_disassem_content): Fix line buffer
overrun due to unchecked strcpy.
gdb/testsuite/ChangeLog:
* gdb.base/tui-layout.c: New file.
* gdb.base/tui-layout.exp: Use tui-layout.c, to ensure that the
disassembly window contains very long lines.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/tui-layout.c | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/tui-layout.exp | 17 | ||||
-rw-r--r-- | gdb/tui/tui-disasm.c | 24 |
5 files changed, 82 insertions, 17 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3b3fea1..b6bd2c1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2016-11-09 Andreas Arnez <arnez@linux.vnet.ibm.com> + + * tui/tui-disasm.c (tui_set_disassem_content): Fix line buffer + overrun due to unchecked strcpy. + 2016-11-09 Tristan Gingold <gingold@adacore.com> * darwin-nat.c (find_inferior_task_it): Fix indentation. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b5319ae..f3cb971 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-11-09 Andreas Arnez <arnez@linux.vnet.ibm.com> + + * gdb.base/tui-layout.c: New file. + * gdb.base/tui-layout.exp: Use tui-layout.c, to ensure that the + disassembly window contains very long lines. + 2016-11-08 Tom Tromey <tom@tromey.com> * gdb.python/py-value.exp (test_value_creation): Make "long" test diff --git a/gdb/testsuite/gdb.base/tui-layout.c b/gdb/testsuite/gdb.base/tui-layout.c new file mode 100644 index 0000000..4049f9b --- /dev/null +++ b/gdb/testsuite/gdb.base/tui-layout.c @@ -0,0 +1,47 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define LONGER_NAME(x) x ## x +#define LONGER(x) LONGER_NAME(x) +#define LONGNAME1 d_this_identifier_of_32_chars_an +#define LONGNAME2 LONGER (LONGER (LONGER (LONGER (LONGER (LONGNAME1))))) + +/* Construct a long identifier name. If SHORT_IDENTIFIERS is set, limit + it to 1024 chars. */ + +#ifdef SHORT_IDENTIFIERS +#define LONGNAME3 LONGNAME2 +#else +#define LONGNAME3 LONGER (LONGER (LONGER (LONGER (LONGER (LONGNAME2))))) +#endif + +void LONGNAME3 (void); + +int +main () +{ + LONGNAME3 (); + return 0; +} + +/* Function with a long name. Placing it after main makes it more likely + to be shown in the disassembly window on startup. */ + +void +LONGNAME3 (void) +{ +} diff --git a/gdb/testsuite/gdb.base/tui-layout.exp b/gdb/testsuite/gdb.base/tui-layout.exp index 43b3a4f..d8cd228 100644 --- a/gdb/testsuite/gdb.base/tui-layout.exp +++ b/gdb/testsuite/gdb.base/tui-layout.exp @@ -13,12 +13,23 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -standard_testfile start.c +standard_testfile -if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile] } { - return -1 +set ccopts {debug quiet} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile" \ + executable $ccopts] != "" } { + # Maybe the compiler can't handle arbitrarily long identfier names. + # Try with a shorter version. + lappend ccopts "additional_flags=-DSHORT_IDENTIFIERS" + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile" \ + executable $ccopts] != "" } { + untested "compile" + return -1 + } } +clean_restart "$binfile" + if {[skip_tui_tests]} { # TUI support is disabled. Check for error message. gdb_test "layout asm" "Undefined command: \"layout\". Try \"help\"." diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c index 29c1443..5368aa4 100644 --- a/gdb/tui/tui-disasm.c +++ b/gdb/tui/tui-disasm.c @@ -172,7 +172,7 @@ tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc) enum tui_status ret = TUI_FAILURE; int i; int offset = TUI_DISASM_WIN->detail.source_info.horizontal_offset; - int max_lines; + int max_lines, line_width; CORE_ADDR cur_pc; struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); int tab_len = tui_default_tab_len (); @@ -193,8 +193,9 @@ tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc) TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr = pc; cur_pc = locator->content[0]->which_element.locator.addr; - max_lines = TUI_DISASM_WIN->generic.height - 2; /* Account for - hilite. */ + /* Window size, excluding highlight box. */ + max_lines = TUI_DISASM_WIN->generic.height - 2; + line_width = TUI_DISASM_WIN->generic.width - 2; /* Get temporary table that will hold all strings (addr & insn). */ asm_lines = XALLOCAVEC (struct tui_asm_line, max_lines); @@ -233,20 +234,15 @@ tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc) src = &element->which_element.source; strcpy (line, asm_lines[i].addr_string); cur_len = strlen (line); - - /* Add spaces to make the instructions start on the same - column. */ - while (cur_len < insn_pos) - { - strcat (line, " "); - cur_len++; - } - - strcat (line, asm_lines[i].insn); + memset (line + cur_len, ' ', insn_pos - cur_len); + strcpy (line + insn_pos, asm_lines[i].insn); /* Now copy the line taking the offset into account. */ if (strlen (line) > offset) - strcpy (src->line, &line[offset]); + { + strncpy (src->line, &line[offset], line_width); + src->line[line_width] = '\0'; + } else src->line[0] = '\0'; |