mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
Prevent a potential illegal memory access in the DWARF parser when processing a corrupt file.
PR 24829 * dwarf.c (check_uvalue): New function. Ensures that a block's size is valid. (read_and_display_attr_value): Use check_value when processsing DW_FORM_block<n> attributes.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2019-08-23 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 24829
|
||||||
|
* dwarf.c (check_uvalue): New function. Ensures that a block's
|
||||||
|
size is valid.
|
||||||
|
(read_and_display_attr_value): Use check_value when processsing
|
||||||
|
DW_FORM_block<n> attributes.
|
||||||
|
|
||||||
2019-08-22 Nick Clifton <nickc@redhat.com>
|
2019-08-22 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR 24921
|
PR 24921
|
||||||
|
@ -1832,6 +1832,34 @@ free_dwo_info (void)
|
|||||||
first_dwo_info = NULL;
|
first_dwo_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure that START + UVALUE is less than END.
|
||||||
|
Return an adjusted UVALUE if necessary to ensure this relationship. */
|
||||||
|
|
||||||
|
static inline dwarf_vma
|
||||||
|
check_uvalue (const unsigned char * start,
|
||||||
|
dwarf_vma uvalue,
|
||||||
|
const unsigned char * end)
|
||||||
|
{
|
||||||
|
dwarf_vma max_uvalue = end - start;
|
||||||
|
|
||||||
|
/* FIXME: Testing "(start + uvalue) < start" miscompiles with gcc 4.8.3
|
||||||
|
running on an x86_64 host in 32-bit mode. So we pre-compute the value
|
||||||
|
here. */
|
||||||
|
const unsigned char * ptr = start + uvalue;
|
||||||
|
|
||||||
|
/* See PR 17512: file: 008-103549-0.001:0.1.
|
||||||
|
and PR 24829 for examples of where these tests are triggered. */
|
||||||
|
if (uvalue > max_uvalue
|
||||||
|
|| ptr > end
|
||||||
|
|| ptr < start)
|
||||||
|
{
|
||||||
|
warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
|
||||||
|
uvalue = max_uvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uvalue;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
read_and_display_attr_value (unsigned long attribute,
|
read_and_display_attr_value (unsigned long attribute,
|
||||||
unsigned long form,
|
unsigned long form,
|
||||||
@ -2056,16 +2084,9 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
uvalue = 0;
|
uvalue = 0;
|
||||||
block_start = end;
|
block_start = end;
|
||||||
}
|
}
|
||||||
/* FIXME: Testing "(block_start + uvalue) < block_start" miscompiles with
|
|
||||||
gcc 4.8.3 running on an x86_64 host in 32-bit mode. So we pre-compute
|
uvalue = check_uvalue (block_start, uvalue, end);
|
||||||
block_start + uvalue here. */
|
|
||||||
data = block_start + uvalue;
|
|
||||||
/* PR 17512: file: 008-103549-0.001:0.1. */
|
|
||||||
if (block_start + uvalue > end || data < block_start)
|
|
||||||
{
|
|
||||||
warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
|
|
||||||
uvalue = end - block_start;
|
|
||||||
}
|
|
||||||
if (do_loc)
|
if (do_loc)
|
||||||
data = block_start + uvalue;
|
data = block_start + uvalue;
|
||||||
else
|
else
|
||||||
@ -2081,12 +2102,9 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
uvalue = 0;
|
uvalue = 0;
|
||||||
block_start = end;
|
block_start = end;
|
||||||
}
|
}
|
||||||
data = block_start + uvalue;
|
|
||||||
if (block_start + uvalue > end || data < block_start)
|
uvalue = check_uvalue (block_start, uvalue, end);
|
||||||
{
|
|
||||||
warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
|
|
||||||
uvalue = end - block_start;
|
|
||||||
}
|
|
||||||
if (do_loc)
|
if (do_loc)
|
||||||
data = block_start + uvalue;
|
data = block_start + uvalue;
|
||||||
else
|
else
|
||||||
@ -2102,12 +2120,9 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
uvalue = 0;
|
uvalue = 0;
|
||||||
block_start = end;
|
block_start = end;
|
||||||
}
|
}
|
||||||
data = block_start + uvalue;
|
|
||||||
if (block_start + uvalue > end || data < block_start)
|
uvalue = check_uvalue (block_start, uvalue, end);
|
||||||
{
|
|
||||||
warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
|
|
||||||
uvalue = end - block_start;
|
|
||||||
}
|
|
||||||
if (do_loc)
|
if (do_loc)
|
||||||
data = block_start + uvalue;
|
data = block_start + uvalue;
|
||||||
else
|
else
|
||||||
@ -2124,14 +2139,9 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
uvalue = 0;
|
uvalue = 0;
|
||||||
block_start = end;
|
block_start = end;
|
||||||
}
|
}
|
||||||
data = block_start + uvalue;
|
|
||||||
if (block_start + uvalue > end
|
uvalue = check_uvalue (block_start, uvalue, end);
|
||||||
/* PR 17531: file: 5b5f0592. */
|
|
||||||
|| data < block_start)
|
|
||||||
{
|
|
||||||
warn (_("Corrupt attribute block length: %lx\n"), (long) uvalue);
|
|
||||||
uvalue = end - block_start;
|
|
||||||
}
|
|
||||||
if (do_loc)
|
if (do_loc)
|
||||||
data = block_start + uvalue;
|
data = block_start + uvalue;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user