PR27853, Infinite loop in dwarf.c

Not quite infinite but much longer than it need be.  The problem is
triggered by read_and_display_attr_value incrementing "data" past
"end".  read_and_display_attr_value shouldn't do that, but be
defensive.

	PR 27853
	* dwarf.c (display_formatted_table): Test for data >= end rather
	than data == end.
	(process_extended_line_op): Likewise.
	(display_debug_lines_raw): Likewise.
	(display_debug_lines_decoded): Likewise.
This commit is contained in:
Alan Modra
2021-05-12 15:11:43 +09:30
parent 5ab3907543
commit 55b26492bb
2 changed files with 21 additions and 12 deletions

@ -1,3 +1,12 @@
2021-05-12 Alan Modra <amodra@gmail.com>
PR 27853
* dwarf.c (display_formatted_table): Test for data >= end rather
than data == end.
(process_extended_line_op): Likewise.
(display_debug_lines_raw): Likewise.
(display_debug_lines_decoded): Likewise.
2021-05-12 Alan Modra <amodra@gmail.com> 2021-05-12 Alan Modra <amodra@gmail.com>
PR 27849 PR 27849

@ -521,7 +521,7 @@ process_extended_line_op (unsigned char * data,
READ_ULEB (len, data, end); READ_ULEB (len, data, end);
header_len = data - orig_data; header_len = data - orig_data;
if (len == 0 || data == end || len > (size_t) (end - data)) if (len == 0 || data >= end || len > (size_t) (end - data))
{ {
warn (_("Badly formed extended line op encountered!\n")); warn (_("Badly formed extended line op encountered!\n"));
return header_len; return header_len;
@ -574,7 +574,7 @@ process_extended_line_op (unsigned char * data,
printf ("%.*s\n\n", (int) l, name); printf ("%.*s\n\n", (int) l, name);
} }
if (((size_t) (data - orig_data) != len + header_len) || data == end) if (((size_t) (data - orig_data) != len + header_len) || data >= end)
warn (_("DW_LNE_define_file: Bad opcode length\n")); warn (_("DW_LNE_define_file: Bad opcode length\n"));
break; break;
@ -4327,7 +4327,7 @@ display_formatted_table (unsigned char *data,
{ {
SKIP_ULEB (data, end); SKIP_ULEB (data, end);
SKIP_ULEB (data, end); SKIP_ULEB (data, end);
if (data == end) if (data >= end)
{ {
warn (_("%s: Corrupt format description entry\n"), table_name); warn (_("%s: Corrupt format description entry\n"), table_name);
return data; return data;
@ -4340,7 +4340,7 @@ display_formatted_table (unsigned char *data,
printf (_("\n The %s is empty.\n"), table_name); printf (_("\n The %s is empty.\n"), table_name);
return data; return data;
} }
else if (data == end) else if (data >= end)
{ {
warn (_("%s: Corrupt entry count - expected %s but none found\n"), warn (_("%s: Corrupt entry count - expected %s but none found\n"),
table_name, dwarf_vmatoa ("x", data_count)); table_name, dwarf_vmatoa ("x", data_count));
@ -4419,7 +4419,7 @@ display_formatted_table (unsigned char *data,
} }
} }
if (data == end && (datai < data_count - 1)) if (data >= end && (datai < data_count - 1))
{ {
warn (_("\n%s: Corrupt entries list\n"), table_name); warn (_("\n%s: Corrupt entries list\n"), table_name);
return data; return data;
@ -4665,7 +4665,7 @@ display_debug_lines_raw (struct dwarf_section * section,
printf ("%s\t", dwarf_vmatoa ("u", val)); printf ("%s\t", dwarf_vmatoa ("u", val));
printf ("%.*s\n", (int)(end - name), name); printf ("%.*s\n", (int)(end - name), name);
if (data == end) if (data >= end)
{ {
warn (_("Corrupt file name table entry\n")); warn (_("Corrupt file name table entry\n"));
break; break;
@ -5013,7 +5013,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
} }
READ_ULEB (n_directories, data, end); READ_ULEB (n_directories, data, end);
if (data == end) if (data >= end)
{ {
warn (_("Corrupt directories list\n")); warn (_("Corrupt directories list\n"));
break; break;
@ -5037,7 +5037,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
READ_ULEB (content_type, format, end); READ_ULEB (content_type, format, end);
READ_ULEB (form, format, end); READ_ULEB (form, format, end);
if (data == end) if (data >= end)
{ {
warn (_("Corrupt directories list\n")); warn (_("Corrupt directories list\n"));
break; break;
@ -5067,7 +5067,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
NULL, 1, section, NULL, 1, section,
NULL, '\t', -1); NULL, '\t', -1);
} }
if (data == end) if (data >= end)
{ {
warn (_("Corrupt directories list\n")); warn (_("Corrupt directories list\n"));
break; break;
@ -5087,7 +5087,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
} }
READ_ULEB (n_files, data, end); READ_ULEB (n_files, data, end);
if (data == end && n_files > 0) if (data >= end && n_files > 0)
{ {
warn (_("Corrupt file name list\n")); warn (_("Corrupt file name list\n"));
break; break;
@ -5112,7 +5112,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
READ_ULEB (content_type, format, end); READ_ULEB (content_type, format, end);
READ_ULEB (form, format, end); READ_ULEB (form, format, end);
if (data == end) if (data >= end)
{ {
warn (_("Corrupt file name list\n")); warn (_("Corrupt file name list\n"));
break; break;
@ -5159,7 +5159,7 @@ display_debug_lines_decoded (struct dwarf_section * section,
NULL, 1, section, NULL, 1, section,
NULL, '\t', -1); NULL, '\t', -1);
} }
if (data == end) if (data >= end)
{ {
warn (_("Corrupt file name list\n")); warn (_("Corrupt file name list\n"));
break; break;