+2014-12-22 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17531
+ * dwarf.c (decode_location_expression): Check for an out of range
+ value for a DW_OP_GNU_entry_value expression.
+ (display_debug_lines_raw): Check for a partial
+ .debug_line. section being encountered without a prior, full
+ .debug.line section.
+ (display_debug_lines_decoded): Likewise. Also check for
+ li_line_range being zero.
+ (display_debug_pubnames_worker): Check for an invalid pn_length
+ field.
+ (read_cie): Add range checks.
+ * elfcomm.c (setup_archive): Check for a negative longnames_size.
+
2014-12-18 Mark Wielaard <mjw@redhat.com>
* dwarf.c (read_and_display_attr_value): Change display name of
case DW_OP_GNU_entry_value:
uvalue = read_uleb128 (data, &bytes_read, end);
data += bytes_read;
+ /* PR 17531: file: 0cc9cd00. */
+ if (uvalue > (dwarf_vma) (end - data))
+ uvalue = end - data;
printf ("DW_OP_GNU_entry_value: (");
if (decode_location_expression (data, pointer_size, offset_size,
dwarf_version, uvalue,
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Partial .debug_line. section encountered without a prior full .debug_line section"));
+ return 0;
+ }
reset_state_machine (linfo.li_default_is_stmt);
}
else
warn (_("Line range of 0 is invalid, using 1 instead\n"));
linfo.li_line_range = 1;
}
-
+
reset_state_machine (linfo.li_default_is_stmt);
/* Display the contents of the Opcodes table. */
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Partial .debug_line. section encountered without a prior full .debug_line section"));
+ return 0;
+ }
reset_state_machine (linfo.li_default_is_stmt);
}
else
& end_of_sequence)) == NULL)
return 0;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Line range of 0 is invalid, using 1 instead\n"));
+ linfo.li_line_range = 1;
+ }
reset_state_machine (linfo.li_default_is_stmt);
/* Save a pointer to the contents of the Opcodes table. */
SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
- start += names.pn_length + initial_length_size;
+ /* PR 17531: file: 7615b6b2. */
+ if ((dwarf_signed_vma) names.pn_length < 0)
+ {
+ warn (_("Negative length for public name: 0x%lx\n"), (long) names.pn_length);
+ start = end;
+ }
+ else
+ start += names.pn_length + initial_length_size;
+
+ printf (_(" Length: %ld\n"),
+ (long) names.pn_length);
+ printf (_(" Version: %d\n"),
+ names.pn_version);
+ printf (_(" Offset into .debug_info section: 0x%lx\n"),
+ (unsigned long) names.pn_offset);
+ printf (_(" Size of area in .debug_info section: %ld\n"),
+ (long) names.pn_size);
if (names.pn_version != 2 && names.pn_version != 3)
{
continue;
}
- printf (_(" Length: %ld\n"),
- (long) names.pn_length);
- printf (_(" Version: %d\n"),
- names.pn_version);
- printf (_(" Offset into .debug_info section: 0x%lx\n"),
- (unsigned long) names.pn_offset);
- printf (_(" Size of area in .debug_info section: %ld\n"),
- (long) names.pn_size);
-
if (is_gnu)
printf (_("\n Offset Kind Name\n"));
else
if (augmentation_data_len)
{
- unsigned char *p, *q;
+ unsigned char *p;
+ unsigned char *q;
+ unsigned char *qend;
+
p = (unsigned char *) fc->augmentation + 1;
q = augmentation_data;
+ qend = q + augmentation_data_len;
+
+ /* PR 17531: file: 015adfaa. */
+ if (qend < q)
+ {
+ warn (_("Negative augmentation data length: 0x%lx"), augmentation_data_len);
+ augmentation_data_len = 0;
+ }
while (p < end && q < augmentation_data + augmentation_data_len)
{
break;
p++;
}
+
+ if (q < qend)
+ {
+ warn (_("Not enough augmentation data (%lx bytes still needed)\n"),
+ (augmentation_data + augmentation_data_len) - q);
+ augmentation_data_len = q - augmentation_data;
+ }
}
*p_cie = fc;