mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
GDB: Fix out of bounds accesses with limited-length values
Fix accesses to limited-length values in `contents_copy_raw' and `contents_copy_raw_bitwise' so that they observe the limit of the original allocation. Reported by Simon Marchi as a heap-buffer-overflow AddressSanitizer issue triggered with gdb.ada/limited-length.exp. Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
17
gdb/value.c
17
gdb/value.c
@ -1168,6 +1168,11 @@ value::contents_copy_raw (struct value *dst, LONGEST dst_offset,
|
||||
mean we'd be copying garbage. */
|
||||
gdb_assert (!dst->m_lazy && !m_lazy);
|
||||
|
||||
ULONGEST copy_length = length;
|
||||
ULONGEST limit = m_limited_length;
|
||||
if (limit > 0 && src_offset + length > limit)
|
||||
copy_length = src_offset > limit ? 0 : limit - src_offset;
|
||||
|
||||
/* The overwritten DST range gets unavailability ORed in, not
|
||||
replaced. Make sure to remember to implement replacing if it
|
||||
turns out actually necessary. */
|
||||
@ -1178,10 +1183,10 @@ value::contents_copy_raw (struct value *dst, LONGEST dst_offset,
|
||||
/* Copy the data. */
|
||||
gdb::array_view<gdb_byte> dst_contents
|
||||
= dst->contents_all_raw ().slice (dst_offset * unit_size,
|
||||
length * unit_size);
|
||||
copy_length * unit_size);
|
||||
gdb::array_view<const gdb_byte> src_contents
|
||||
= contents_all_raw ().slice (src_offset * unit_size,
|
||||
length * unit_size);
|
||||
copy_length * unit_size);
|
||||
gdb::copy (src_contents, dst_contents);
|
||||
|
||||
/* Copy the meta-data, adjusted. */
|
||||
@ -1206,6 +1211,12 @@ value::contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
|
||||
mean we'd be copying garbage. */
|
||||
gdb_assert (!dst->m_lazy && !m_lazy);
|
||||
|
||||
ULONGEST copy_bit_length = bit_length;
|
||||
ULONGEST bit_limit = m_limited_length * TARGET_CHAR_BIT;
|
||||
if (bit_limit > 0 && src_bit_offset + bit_length > bit_limit)
|
||||
copy_bit_length = (src_bit_offset > bit_limit ? 0
|
||||
: bit_limit - src_bit_offset);
|
||||
|
||||
/* The overwritten DST range gets unavailability ORed in, not
|
||||
replaced. Make sure to remember to implement replacing if it
|
||||
turns out actually necessary. */
|
||||
@ -1220,7 +1231,7 @@ value::contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
|
||||
gdb::array_view<const gdb_byte> src_contents = contents_all_raw ();
|
||||
copy_bitwise (dst_contents.data (), dst_bit_offset,
|
||||
src_contents.data (), src_bit_offset,
|
||||
bit_length,
|
||||
copy_bit_length,
|
||||
type_byte_order (type ()) == BFD_ENDIAN_BIG);
|
||||
|
||||
/* Copy the meta-data. */
|
||||
|
Reference in New Issue
Block a user