mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
get_line_filename_and_dirname
* dwarf.c (get_line_filename_and_dirname): Delete initial_length_size. Simplify length sanity check, and check for too small lengths. Constrain data reads to header length. Avoid pointer UB.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* dwarf.c (get_line_filename_and_dirname): Delete initial_length_size.
|
||||||
|
Simplify length sanity check, and check for too small lengths.
|
||||||
|
Constrain data reads to header length. Avoid pointer UB.
|
||||||
|
|
||||||
2021-05-15 Alan Modra <amodra@gmail.com>
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* dwarf.c (display_debug_macinfo): Print strings that might not
|
* dwarf.c (display_debug_macinfo): Print strings that might not
|
||||||
|
@ -5827,7 +5827,7 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
|
|||||||
{
|
{
|
||||||
struct dwarf_section *section = &debug_displays [line].section;
|
struct dwarf_section *section = &debug_displays [line].section;
|
||||||
unsigned char *hdrptr, *dirtable, *file_name;
|
unsigned char *hdrptr, *dirtable, *file_name;
|
||||||
unsigned int offset_size, initial_length_size;
|
unsigned int offset_size;
|
||||||
unsigned int version, opcode_base;
|
unsigned int version, opcode_base;
|
||||||
dwarf_vma length, diridx;
|
dwarf_vma length, diridx;
|
||||||
const unsigned char * end;
|
const unsigned char * end;
|
||||||
@ -5847,16 +5847,14 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
|
|||||||
/* This section is 64-bit DWARF 3. */
|
/* This section is 64-bit DWARF 3. */
|
||||||
SAFE_BYTE_GET_AND_INC (length, hdrptr, 8, end);
|
SAFE_BYTE_GET_AND_INC (length, hdrptr, 8, end);
|
||||||
offset_size = 8;
|
offset_size = 8;
|
||||||
initial_length_size = 12;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
offset_size = 4;
|
offset_size = 4;
|
||||||
initial_length_size = 4;
|
|
||||||
}
|
if (length > (size_t) (end - hdrptr)
|
||||||
if (length + initial_length_size < length
|
|| length < 2 + offset_size + 1 + 3 + 1)
|
||||||
|| length + initial_length_size > section->size)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
end = hdrptr + length;
|
||||||
|
|
||||||
SAFE_BYTE_GET_AND_INC (version, hdrptr, 2, end);
|
SAFE_BYTE_GET_AND_INC (version, hdrptr, 2, end);
|
||||||
if (version != 2 && version != 3 && version != 4)
|
if (version != 2 && version != 3 && version != 4)
|
||||||
@ -5867,18 +5865,19 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
|
|||||||
hdrptr += 3; /* Skip default_is_stmt, line_base, line_range. */
|
hdrptr += 3; /* Skip default_is_stmt, line_base, line_range. */
|
||||||
|
|
||||||
SAFE_BYTE_GET_AND_INC (opcode_base, hdrptr, 1, end);
|
SAFE_BYTE_GET_AND_INC (opcode_base, hdrptr, 1, end);
|
||||||
if (opcode_base == 0)
|
if (opcode_base == 0
|
||||||
|
|| opcode_base - 1 >= (size_t) (end - hdrptr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hdrptr += opcode_base - 1;
|
hdrptr += opcode_base - 1;
|
||||||
if (hdrptr >= end)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dirtable = hdrptr;
|
dirtable = hdrptr;
|
||||||
/* Skip over dirname table. */
|
/* Skip over dirname table. */
|
||||||
while (*hdrptr != '\0')
|
while (*hdrptr != '\0')
|
||||||
{
|
{
|
||||||
hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
|
hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
|
||||||
|
if (hdrptr < end)
|
||||||
|
hdrptr++;
|
||||||
if (hdrptr >= end)
|
if (hdrptr >= end)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -5887,7 +5886,9 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
|
|||||||
/* Now skip over preceding filename table entries. */
|
/* Now skip over preceding filename table entries. */
|
||||||
for (; hdrptr < end && *hdrptr != '\0' && fileidx > 1; fileidx--)
|
for (; hdrptr < end && *hdrptr != '\0' && fileidx > 1; fileidx--)
|
||||||
{
|
{
|
||||||
hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
|
hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
|
||||||
|
if (hdrptr < end)
|
||||||
|
hdrptr++;
|
||||||
SKIP_ULEB (hdrptr, end);
|
SKIP_ULEB (hdrptr, end);
|
||||||
SKIP_ULEB (hdrptr, end);
|
SKIP_ULEB (hdrptr, end);
|
||||||
SKIP_ULEB (hdrptr, end);
|
SKIP_ULEB (hdrptr, end);
|
||||||
@ -5896,14 +5897,20 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
file_name = hdrptr;
|
file_name = hdrptr;
|
||||||
hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
|
hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
|
||||||
|
if (hdrptr < end)
|
||||||
|
hdrptr++;
|
||||||
if (hdrptr >= end)
|
if (hdrptr >= end)
|
||||||
return NULL;
|
return NULL;
|
||||||
READ_ULEB (diridx, hdrptr, end);
|
READ_ULEB (diridx, hdrptr, end);
|
||||||
if (diridx == 0)
|
if (diridx == 0)
|
||||||
return file_name;
|
return file_name;
|
||||||
for (; dirtable < end && *dirtable != '\0' && diridx > 1; diridx--)
|
for (; dirtable < end && *dirtable != '\0' && diridx > 1; diridx--)
|
||||||
dirtable += strnlen ((char *) dirtable, end - dirtable) + 1;
|
{
|
||||||
|
dirtable += strnlen ((char *) dirtable, end - dirtable);
|
||||||
|
if (dirtable < end)
|
||||||
|
dirtable++;
|
||||||
|
}
|
||||||
if (dirtable >= end || *dirtable == '\0')
|
if (dirtable >= end || *dirtable == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
*dir_name = dirtable;
|
*dir_name = dirtable;
|
||||||
|
Reference in New Issue
Block a user