aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShahab Vahedi <shahab@synopsys.com>2020-01-06 15:27:32 +0100
committerPedro Alves <palves@redhat.com>2020-01-06 19:47:20 +0000
commitcbfa85811792ca8e96ace40bef0aaaf507e54bcc (patch)
tree6cb59c31bf71bc95e6212e74ca32b475a62acc88
parent3f6028216b1df14a299a9cd89b1149258c024d4f (diff)
downloadgdb-cbfa85811792ca8e96ace40bef0aaaf507e54bcc.zip
gdb-cbfa85811792ca8e96ace40bef0aaaf507e54bcc.tar.gz
gdb-cbfa85811792ca8e96ace40bef0aaaf507e54bcc.tar.bz2
GDB: Fix the overflow in addr/line_is_displayed()
In tui_disasm_window::addr_is_displayed(), there can be situations where "content" is empty. For instance, it can happen when the "content" was not filled in tui_disasm_window::set_contents(), because tui_disassemble() threw an exception. Usually this exception is the result of fetching invalid PC addresses like the ones beyond the end of the program. Having "content.size ()" zero leads to an overflow in this condition check inside tui_disasm_window::addr_is_displayed(): int i = 0; while (i < content.size () - threshold ...) { ... content[i] ... } "threshold" is 2 and there are times that "content.size ()" is 0. This results into an overflow and the loop is entered whereas it should have been skipped. Finally, "content[i]" access leads to a segmentation fault. Same problem applies to tui_source_window::line_is_displayed(). The issue has been discussed at length in bug 25345: https://sourceware.org/bugzilla/show_bug.cgi?id=25345 This commit avoids the segmentation faults with an early check: if (content.size () < SCROLL_THRESHOLD) return false; Moreover, those functions have been overhauled to a leaner code. gdb/ChangeLog: 2020-01-06 Shahab Vahedi <shahab@synopsys.com> * tui/tui-disasm.c (tui_disasm_window::addr_is_displayed): Avoid overflow by an early check of content vs threshold. * tui/tui-source.c (tui_source_window::line_is_displayed): Likewise.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/tui/tui-disasm.c16
-rw-r--r--gdb/tui/tui-source.c17
3 files changed, 22 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 69e426e..476712e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2020-01-06 Shahab Vahedi <shahab@synopsys.com>
+
+ * tui/tui-disasm.c (tui_disasm_window::addr_is_displayed): Avoid
+ overflow by an early check of content vs threshold.
+ * tui/tui-source.c (tui_source_window::line_is_displayed):
+ Likewise.
+
2020-01-06 Eli Zaretskii <eliz@gnu.org>
* NEWS: Mention the recent fix of $_exitsignal on MS-Windows.
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index ebd0ba3..98c691f 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -348,19 +348,17 @@ tui_disasm_window::location_matches_p (struct bp_location *loc, int line_no)
bool
tui_disasm_window::addr_is_displayed (CORE_ADDR addr) const
{
- bool is_displayed = false;
- int threshold = SCROLL_THRESHOLD;
+ if (content.size () < SCROLL_THRESHOLD)
+ return false;
- int i = 0;
- while (i < content.size () - threshold && !is_displayed)
+ for (size_t i = 0; i < content.size () - SCROLL_THRESHOLD; ++i)
{
- is_displayed
- = (content[i].line_or_addr.loa == LOA_ADDRESS
- && content[i].line_or_addr.u.addr == addr);
- i++;
+ if (content[i].line_or_addr.loa == LOA_ADDRESS
+ && content[i].line_or_addr.u.addr == addr)
+ return true;
}
- return is_displayed;
+ return false;
}
void
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index e028b72..1503cd4 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -174,18 +174,17 @@ tui_source_window::location_matches_p (struct bp_location *loc, int line_no)
bool
tui_source_window::line_is_displayed (int line) const
{
- bool is_displayed = false;
- int threshold = SCROLL_THRESHOLD;
- int i = 0;
- while (i < content.size () - threshold && !is_displayed)
+ if (content.size () < SCROLL_THRESHOLD)
+ return false;
+
+ for (size_t i = 0; i < content.size () - SCROLL_THRESHOLD; ++i)
{
- is_displayed
- = (content[i].line_or_addr.loa == LOA_LINE
- && content[i].line_or_addr.u.line_no == line);
- i++;
+ if (content[i].line_or_addr.loa == LOA_LINE
+ && content[i].line_or_addr.u.line_no == line)
+ return true;
}
- return is_displayed;
+ return false;
}
void