From 568c1b9f503649d19ed1d17e6970f212e6b6317d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Fri, 24 Mar 2017 15:12:53 +0000 Subject: Avoid segfault on invalid directory table gdb was segfaulting during backtrace on a binary here, where fe->dir_index parsed from the DWARF info was seen to access beyond the provided include_dirs array. This commit bounds the access to entries actually written to the array, and was verified to output the backtrace correctly. gdb/ChangeLog: * dwarf2read.c (setup_type_unit_groups): Ensure dir_index doesn't reference beyond the 'lh->include_dirs' array before accessing to it. (psymtab_include_file_name): Likewise. (dwarf_decode_lines_1): Likewise. (dwarf_decode_lines): Likewise. (file_file_name): Likewise. --- gdb/ChangeLog | 10 ++++++++++ gdb/dwarf2read.c | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5ad7ac3..dd12d3c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2017-03-24 Pádraig Brady + + * dwarf2read.c (setup_type_unit_groups): Ensure dir_index doesn't + reference beyond the 'lh->include_dirs' array before accessing to + it. + (psymtab_include_file_name): Likewise. + (dwarf_decode_lines_1): Likewise. + (dwarf_decode_lines): Likewise. + (file_file_name): Likewise. + 2017-03-23 Simon Marchi * fbsd-tdep.c (fbsd_corefile_thread): Don't set/restore diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b3ea52b..519550b 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -9416,7 +9416,8 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu) const char *dir = NULL; struct file_entry *fe = &lh->file_names[i]; - if (fe->dir_index && lh->include_dirs != NULL) + if (fe->dir_index && lh->include_dirs != NULL + && (fe->dir_index - 1) < lh->num_include_dirs) dir = lh->include_dirs[fe->dir_index - 1]; dwarf2_start_subfile (fe->name, dir); @@ -17985,7 +17986,8 @@ psymtab_include_file_name (const struct line_header *lh, int file_index, char *copied_name = NULL; int file_is_pst; - if (fe.dir_index && lh->include_dirs != NULL) + if (fe.dir_index && lh->include_dirs != NULL + && (fe.dir_index - 1) < lh->num_include_dirs) dir_name = lh->include_dirs[fe.dir_index - 1]; if (!IS_ABSOLUTE_PATH (include_name) @@ -18366,7 +18368,8 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, struct file_entry *fe = &lh->file_names[state_machine.file - 1]; const char *dir = NULL; - if (fe->dir_index && lh->include_dirs != NULL) + if (fe->dir_index && lh->include_dirs != NULL + && (fe->dir_index - 1) < lh->num_include_dirs) dir = lh->include_dirs[fe->dir_index - 1]; dwarf2_start_subfile (fe->name, dir); @@ -18529,7 +18532,8 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, else { fe = &lh->file_names[state_machine.file - 1]; - if (fe->dir_index && lh->include_dirs != NULL) + if (fe->dir_index && lh->include_dirs != NULL + && (fe->dir_index - 1) < lh->num_include_dirs) dir = lh->include_dirs[fe->dir_index - 1]; if (record_lines_p) { @@ -18671,7 +18675,8 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, struct file_entry *fe; fe = &lh->file_names[i]; - if (fe->dir_index && lh->include_dirs != NULL) + if (fe->dir_index && lh->include_dirs != NULL + && (fe->dir_index - 1) < lh->num_include_dirs) dir = lh->include_dirs[fe->dir_index - 1]; dwarf2_start_subfile (fe->name, dir); @@ -21380,7 +21385,8 @@ file_file_name (int file, struct line_header *lh) struct file_entry *fe = &lh->file_names[file - 1]; if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0 - || lh->include_dirs == NULL) + || lh->include_dirs == NULL + || (fe->dir_index - 1) >= lh->num_include_dirs) return xstrdup (fe->name); return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING, fe->name, (char *) NULL); -- cgit v1.1