mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 04:00:07 +08:00
PR25197, assertion fail coffgen.c
The testcase in this PR triggered "BFD_ASSERT (p2->is_sym)" by sneakily generating a C_FILE sym whose value pointed into auxents. The fix then is in the last changed line of this patch, to check p->is_sym as well as p->u.syment.n_sclass. The other changes fix various overflow checks that weren't as solid as they could be. PR 25197 * coffgen.c (coff_find_nearest_line_with_names): Check that C_FILE u.syment.n_value does point at another C_FILE sym and not into some auxent that happens to look like a C_FILE. Properly check for integer overflow and avoid possible pointer wrap-around. Simplify pr17512 checks.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2019-11-19 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 25197
|
||||||
|
* coffgen.c (coff_find_nearest_line_with_names): Check that C_FILE
|
||||||
|
u.syment.n_value does point at another C_FILE sym and not into
|
||||||
|
some auxent that happens to look like a C_FILE. Properly check
|
||||||
|
for integer overflow and avoid possible pointer wrap-around.
|
||||||
|
Simplify pr17512 checks.
|
||||||
|
|
||||||
2019-11-19 Alan Modra <amodra@gmail.com>
|
2019-11-19 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 25200
|
PR 25200
|
||||||
|
@ -1814,10 +1814,11 @@ coff_get_normalized_symtab (bfd *abfd)
|
|||||||
if (! _bfd_coff_get_external_symbols (abfd))
|
if (! _bfd_coff_get_external_symbols (abfd))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
|
size = obj_raw_syment_count (abfd);
|
||||||
/* Check for integer overflow. */
|
/* Check for integer overflow. */
|
||||||
if (size < obj_raw_syment_count (abfd))
|
if (size > (bfd_size_type) -1 / sizeof (combined_entry_type))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
size *= sizeof (combined_entry_type);
|
||||||
internal = (combined_entry_type *) bfd_zalloc (abfd, size);
|
internal = (combined_entry_type *) bfd_zalloc (abfd, size);
|
||||||
if (internal == NULL && size != 0)
|
if (internal == NULL && size != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1844,29 +1845,20 @@ coff_get_normalized_symtab (bfd *abfd)
|
|||||||
symbol_ptr = internal_ptr;
|
symbol_ptr = internal_ptr;
|
||||||
internal_ptr->is_sym = TRUE;
|
internal_ptr->is_sym = TRUE;
|
||||||
|
|
||||||
/* PR 17512: file: 1353-1166-0.004. */
|
|
||||||
if (symbol_ptr->u.syment.n_sclass == C_FILE
|
|
||||||
&& symbol_ptr->u.syment.n_numaux > 0
|
|
||||||
&& raw_src + symesz + symbol_ptr->u.syment.n_numaux
|
|
||||||
* symesz > raw_end)
|
|
||||||
{
|
|
||||||
bfd_release (abfd, internal);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
i < symbol_ptr->u.syment.n_numaux;
|
i < symbol_ptr->u.syment.n_numaux;
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
internal_ptr++;
|
internal_ptr++;
|
||||||
|
raw_src += symesz;
|
||||||
|
|
||||||
/* PR 17512: Prevent buffer overrun. */
|
/* PR 17512: Prevent buffer overrun. */
|
||||||
if (internal_ptr >= internal_end)
|
if (raw_src >= raw_end || internal_ptr >= internal_end)
|
||||||
{
|
{
|
||||||
bfd_release (abfd, internal);
|
bfd_release (abfd, internal);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_src += symesz;
|
|
||||||
bfd_coff_swap_aux_in (abfd, (void *) raw_src,
|
bfd_coff_swap_aux_in (abfd, (void *) raw_src,
|
||||||
symbol_ptr->u.syment.n_type,
|
symbol_ptr->u.syment.n_type,
|
||||||
symbol_ptr->u.syment.n_sclass,
|
symbol_ptr->u.syment.n_sclass,
|
||||||
@ -2408,13 +2400,16 @@ coff_find_nearest_line_with_names (bfd *abfd,
|
|||||||
maxdiff = offset + sec_vma - p2->u.syment.n_value;
|
maxdiff = offset + sec_vma - p2->u.syment.n_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->u.syment.n_value >= cof->raw_syment_count)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Avoid endless loops on erroneous files by ensuring that
|
/* Avoid endless loops on erroneous files by ensuring that
|
||||||
we always move forward in the file. */
|
we always move forward in the file. */
|
||||||
if (p >= cof->raw_syments + p->u.syment.n_value)
|
if (p >= cof->raw_syments + p->u.syment.n_value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
p = cof->raw_syments + p->u.syment.n_value;
|
p = cof->raw_syments + p->u.syment.n_value;
|
||||||
if (p > pend || p->u.syment.n_sclass != C_FILE)
|
if (!p->is_sym || p->u.syment.n_sclass != C_FILE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user