aboutsummaryrefslogtreecommitdiff
path: root/binutils/dwarf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-10-05 17:32:18 +1030
committerAlan Modra <amodra@gmail.com>2017-10-05 17:43:34 +1030
commit9c0f3d3f2017829ffd908c9893b85094985c3b58 (patch)
tree5923acc679c5289d96b9e10c2feec203eb808c57 /binutils/dwarf.c
parentc91933e9e33654c7b8973cb449b93f5152afcbcb (diff)
downloadgdb-9c0f3d3f2017829ffd908c9893b85094985c3b58.zip
gdb-9c0f3d3f2017829ffd908c9893b85094985c3b58.tar.gz
gdb-9c0f3d3f2017829ffd908c9893b85094985c3b58.tar.bz2
PR22239 - invalid memory read in display_debug_frames
Pointer comparisons have traps for the unwary. After adding a large unknown value to "start", the test "start < end" depends on where "start" is originally in memory. PR 22239 * dwarf.c (read_cie): Don't compare "start" and "end" pointers after adding a possibly wild length to "start", compare the length to the difference of the pointers instead. Remove now redundant "negative" length test.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r--binutils/dwarf.c15
1 files changed, 4 insertions, 11 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 7ded1bf..f8c726c 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -7001,14 +7001,14 @@ read_cie (unsigned char *start, unsigned char *end,
{
READ_ULEB (augmentation_data_len);
augmentation_data = start;
- start += augmentation_data_len;
/* PR 17512: file: 11042-2589-0.004. */
- if (start > end)
+ if (augmentation_data_len > (size_t) (end - start))
{
warn (_("Augmentation data too long: %#lx, expected at most %#lx\n"),
- augmentation_data_len, (long)((end - start) + augmentation_data_len));
+ augmentation_data_len, (unsigned long) (end - start));
return end;
}
+ start += augmentation_data_len;
}
if (augmentation_data_len)
@@ -7021,14 +7021,7 @@ read_cie (unsigned char *start, unsigned char *end,
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)
+ while (p < end && q < qend)
{
if (*p == 'L')
q++;