diff options
author | Alan Modra <amodra@gmail.com> | 2017-10-05 17:32:18 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-10-05 17:43:34 +1030 |
commit | 9c0f3d3f2017829ffd908c9893b85094985c3b58 (patch) | |
tree | 5923acc679c5289d96b9e10c2feec203eb808c57 /binutils/dwarf.c | |
parent | c91933e9e33654c7b8973cb449b93f5152afcbcb (diff) | |
download | gdb-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.c | 15 |
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++; |