aboutsummaryrefslogtreecommitdiff
path: root/bfd/libbfd.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-05-21 22:34:34 +0930
committerAlan Modra <amodra@gmail.com>2021-05-22 17:23:24 +0930
commit574ec1084d28ee56710ea48eb072e5c47226d247 (patch)
tree896e94db8291202128699acf9feec022f8a25db7 /bfd/libbfd.c
parent1f1fb219fdc4f96fd967e6173e9090c4c4917e96 (diff)
downloadgdb-574ec1084d28ee56710ea48eb072e5c47226d247.zip
gdb-574ec1084d28ee56710ea48eb072e5c47226d247.tar.gz
gdb-574ec1084d28ee56710ea48eb072e5c47226d247.tar.bz2
bfd dwarf2 sanity checking
This patch is aimed at the many places in dwarf2.c that blindly increment a data pointer after calling functions that are meant to read a fixed number of bytes. The problem with that is with damaged dwarf we might increment a data pointer past the end of data, which is UB and complicates (ie. bugs likely) any further use of that data pointer. To fix those problems, I've moved incrementing of the data pointer into the functions that do the reads. _bfd_safe_read_leb128 gets the same treatment for consistency. * libbfd.c (_bfd_safe_read_leb128): Remove length_return parameter. Replace data pointer with pointer to pointer. Increment pointer over bytes read. * libbfd-in.h (_bfd_safe_read_leb128): Update prototype. * elf-attrs.c (_bfd_elf_parse_attributes): Adjust to suit. Be careful not to increment data pointer past end. Remove now redundant pr17512 check. * wasm-module.c (READ_LEB128): Adjust to suit changes to _bfd_safe_read_leb128. * dwarf2.c (read_n_bytes): New inline function, old one renamed to.. (read_blk): ..this. Allocate and return block. Increment bfd_byte** arg. (read_3_bytes): New function. (read_1_byte, read_1_signed_byte, read_2_bytes, read_4_bytes), (read_8_bytes, read_string, read_indirect_string), (read_indirect_line_string, read_alt_indirect_string): Take a byte_byte** arg which is incremented over bytes read. Remove any bytes_read return. Rewrite limit checks to compare lengths rather than pointers. (read_abbrevs, read_attribute_value, read_formatted_entries), (decode_line_info, find_abstract_instance, read_ranges), (read_rnglists, scan_unit_for_symbols, parse_comp_unit), (stash_comp_unit): Adjust to suit. Rewrite limit checks to compare lengths rather than pointers. * libbfd.h: Regenerate.
Diffstat (limited to 'bfd/libbfd.c')
-rw-r--r--bfd/libbfd.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 892f291..dd98e1b 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -1170,28 +1170,26 @@ _bfd_read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
return result;
}
-/* Read in a LEB128 encoded value from ABFD starting at DATA.
+/* Read in a LEB128 encoded value from ABFD starting at *PTR.
If SIGN is true, return a signed LEB128 value.
- If LENGTH_RETURN is not NULL, return in it the number of bytes read.
+ *PTR is incremented by the number of bytes read.
No bytes will be read at address END or beyond. */
bfd_vma
_bfd_safe_read_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
- bfd_byte *data,
- unsigned int *length_return,
+ bfd_byte **ptr,
bool sign,
const bfd_byte * const end)
{
bfd_vma result = 0;
- unsigned int num_read = 0;
unsigned int shift = 0;
unsigned char byte = 0;
+ bfd_byte *data = *ptr;
while (data < end)
{
byte = bfd_get_8 (abfd, data);
data++;
- num_read++;
if (shift < 8 * sizeof (result))
{
result |= ((bfd_vma) (byte & 0x7f)) << shift;
@@ -1201,8 +1199,7 @@ _bfd_safe_read_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
break;
}
- if (length_return != NULL)
- *length_return = num_read;
+ *ptr = data;
if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
result |= -((bfd_vma) 1 << shift);