forked from Imagelibrary/binutils-gdb
PR29948, heap-buffer-overflow in display_debug_lines_decoded
This fixes a couple of places in display_debug_lines_decoded that were off by one in checking DWARF5 .debug_line directory indices. It also displays the DWARF5 entry 0 for the program current directory rather than "." as is done for pre-DWARF5. I decided against displaying DW_AT_comp_dir for pre-DWARF5 since I figure it is better for readelf to minimally interpret debug info. binutils/ PR 29948 * dwarf.c (display_debug_lines_decoded): Display the given directory entry 0 for DWARF5. Properly check directory index against number of entries in the table. Revert to using unsigned int for n_directories and associated variables. Correct warning messages. gas/ * testsuite/gas/elf/dwarf-5-loc0.d: Update.
This commit is contained in:
118
binutils/dwarf.c
118
binutils/dwarf.c
@@ -4899,7 +4899,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
|
||||
File_Entry *file_table = NULL;
|
||||
unsigned int n_files = 0;
|
||||
char **directory_table = NULL;
|
||||
uint64_t n_directories = 0;
|
||||
unsigned int n_directories = 0;
|
||||
|
||||
if (startswith (section->name, ".debug_line.")
|
||||
/* Note: the following does not apply to .debug_line.dwo sections.
|
||||
@@ -4949,8 +4949,8 @@ display_debug_lines_decoded (struct dwarf_section * section,
|
||||
|
||||
if (linfo.li_version >= 5)
|
||||
{
|
||||
unsigned char *format_start, format_count, *format;
|
||||
uint64_t formati, entryi;
|
||||
unsigned char *format_start, *format;
|
||||
unsigned int format_count, formati, entryi;
|
||||
|
||||
load_debug_section_with_follow (line_str, fileptr);
|
||||
|
||||
@@ -5218,22 +5218,25 @@ display_debug_lines_decoded (struct dwarf_section * section,
|
||||
unsigned int ix = file_table[0].directory_index;
|
||||
const char *directory;
|
||||
|
||||
if (ix == 0)
|
||||
if (ix == 0 && linfo.li_version < 5)
|
||||
directory = ".";
|
||||
/* PR 20439 */
|
||||
else if (n_directories == 0)
|
||||
directory = _("<unknown>");
|
||||
else if (ix > n_directories)
|
||||
{
|
||||
warn (_("directory index %u > number of directories %" PRIu64 "\n"),
|
||||
ix, n_directories);
|
||||
directory = _("<corrupt>");
|
||||
}
|
||||
else if (linfo.li_version >= 5)
|
||||
directory = directory_table[ix];
|
||||
else
|
||||
directory = directory_table[ix - 1];
|
||||
|
||||
{
|
||||
if (linfo.li_version < 5)
|
||||
--ix;
|
||||
if (ix >= n_directories)
|
||||
{
|
||||
warn (_("directory index %u "
|
||||
">= number of directories %u\n"),
|
||||
ix, n_directories);
|
||||
directory = _("<corrupt>");
|
||||
}
|
||||
else
|
||||
directory = directory_table[ix];
|
||||
}
|
||||
if (do_wide)
|
||||
printf (_("CU: %s/%s:\n"),
|
||||
null_name (directory),
|
||||
@@ -5397,45 +5400,53 @@ display_debug_lines_decoded (struct dwarf_section * section,
|
||||
READ_ULEB (uladv, data, end);
|
||||
state_machine_regs.file = uladv;
|
||||
|
||||
{
|
||||
unsigned file = state_machine_regs.file;
|
||||
unsigned dir;
|
||||
unsigned file = state_machine_regs.file;
|
||||
if (linfo.li_version < 5)
|
||||
--file;
|
||||
|
||||
if (linfo.li_version < 5)
|
||||
--file;
|
||||
|
||||
if (file_table == NULL || n_files == 0)
|
||||
printf (_("\n [Use file table entry %d]\n"), file);
|
||||
/* PR 20439 */
|
||||
else if (file >= n_files)
|
||||
{
|
||||
warn (_("file index %u > number of files %u\n"), file, n_files);
|
||||
printf (_("\n <over large file table index %u>"), file);
|
||||
}
|
||||
else if ((dir = file_table[file].directory_index) == 0)
|
||||
/* If directory index is 0, that means current directory. */
|
||||
printf ("\n./%s:[++]\n", null_name (file_table[file].name));
|
||||
else if (directory_table == NULL || n_directories == 0)
|
||||
printf (_("\n [Use file %s in directory table entry %d]\n"),
|
||||
null_name (file_table[file].name), dir);
|
||||
/* PR 20439 */
|
||||
else if (dir > n_directories)
|
||||
{
|
||||
warn (_("directory index %u > number of directories %" PRIu64 "\n"),
|
||||
dir, n_directories);
|
||||
printf (_("\n <over large directory table entry %u>\n"), dir);
|
||||
}
|
||||
else if (linfo.li_version >= 5)
|
||||
printf ("\n%s/%s:\n",
|
||||
/* The directory index starts counting at 0. */
|
||||
null_name (directory_table[dir]),
|
||||
null_name (file_table[file].name));
|
||||
else
|
||||
printf ("\n%s/%s:\n",
|
||||
/* The directory index starts counting at 1. */
|
||||
null_name (directory_table[dir - 1]),
|
||||
null_name (file_table[file].name));
|
||||
}
|
||||
if (file_table == NULL || n_files == 0)
|
||||
printf (_("\n [Use file table entry %d]\n"), file);
|
||||
/* PR 20439 */
|
||||
else if (file >= n_files)
|
||||
{
|
||||
warn (_("file index %u >= number of files %u\n"),
|
||||
file, n_files);
|
||||
printf (_("\n <over large file table index %u>"), file);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned dir = file_table[file].directory_index;
|
||||
if (dir == 0 && linfo.li_version < 5)
|
||||
/* If directory index is 0, that means compilation
|
||||
current directory. bfd/dwarf2.c shows
|
||||
DW_AT_comp_dir here but in keeping with the
|
||||
readelf practice of minimal interpretation of
|
||||
file data, we show "./". */
|
||||
printf ("\n./%s:[++]\n",
|
||||
null_name (file_table[file].name));
|
||||
else if (directory_table == NULL || n_directories == 0)
|
||||
printf (_("\n [Use file %s "
|
||||
"in directory table entry %d]\n"),
|
||||
null_name (file_table[file].name), dir);
|
||||
else
|
||||
{
|
||||
if (linfo.li_version < 5)
|
||||
--dir;
|
||||
/* PR 20439 */
|
||||
if (dir >= n_directories)
|
||||
{
|
||||
warn (_("directory index %u "
|
||||
">= number of directories %u\n"),
|
||||
dir, n_directories);
|
||||
printf (_("\n <over large directory table entry "
|
||||
"%u>\n"), dir);
|
||||
}
|
||||
else
|
||||
printf ("\n%s/%s:\n",
|
||||
null_name (directory_table[dir]),
|
||||
null_name (file_table[file].name));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_LNS_set_column:
|
||||
@@ -5530,7 +5541,8 @@ display_debug_lines_decoded (struct dwarf_section * section,
|
||||
/* PR 20439 */
|
||||
if (indx >= n_files)
|
||||
{
|
||||
warn (_("corrupt file index %u encountered\n"), indx);
|
||||
warn (_("file index %u >= number of files %u\n"),
|
||||
indx, n_files);
|
||||
fileName = _("<corrupt>");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
Contents of the \.debug_line section:
|
||||
|
||||
CU: \./foo\.c:
|
||||
CU: .*/gas/testsuite/foo\.c:
|
||||
File name +Line number +Starting address +View +Stmt
|
||||
|
||||
\./foo.c:\[\+\+\]
|
||||
.*/gas/testsuite/foo.c:
|
||||
foo\.c +1 +0x8 +x
|
||||
foo\.c +2 +0x10 +x
|
||||
foo\.c +- +0x10
|
||||
|
||||
Reference in New Issue
Block a user