aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-12-30 11:41:16 +1030
committerAlan Modra <amodra@gmail.com>2022-12-30 21:31:19 +1030
commita984f112b015b7d33c3c91230eb4c35695926539 (patch)
treee281f75aef778bb92811dd00359ed86a60ee99b5
parentfb4646cf1ae4efb70714c323797707e8e09055a0 (diff)
downloadbinutils-a984f112b015b7d33c3c91230eb4c35695926539.zip
binutils-a984f112b015b7d33c3c91230eb4c35695926539.tar.gz
binutils-a984f112b015b7d33c3c91230eb4c35695926539.tar.bz2
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.
-rw-r--r--binutils/dwarf.c116
-rw-r--r--gas/testsuite/gas/elf/dwarf-5-loc0.d4
2 files changed, 66 insertions, 54 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index a00568d..cac26ad 100644
--- a/binutils/dwarf.c
+++ b/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)
+ else
{
- warn (_("directory index %u > number of directories %" PRIu64 "\n"),
- ix, n_directories);
- directory = _("<corrupt>");
+ 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];
}
- else if (linfo.li_version >= 5)
- directory = directory_table[ix];
- else
- directory = directory_table[ix - 1];
-
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;
-
- if (linfo.li_version < 5)
- --file;
+ unsigned file = state_machine_regs.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
diff --git a/gas/testsuite/gas/elf/dwarf-5-loc0.d b/gas/testsuite/gas/elf/dwarf-5-loc0.d
index 7e8473a..9439d10 100644
--- a/gas/testsuite/gas/elf/dwarf-5-loc0.d
+++ b/gas/testsuite/gas/elf/dwarf-5-loc0.d
@@ -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