Don't segv on cie.initial_instructions[] overflow.
Don't attempt to merge CIEs with a larger number of insns than will fit in the buffer. * elf-eh-frame.c (cie_eq): Return false when initial_insn_length is too large. (cie_compute_hash): Don't exceed bounds of initial_instructions. (_bfd_elf_parse_eh_frame): Always set initial_insn_length, and save as much of insns to initial_instructions[] as will fit.
This commit is contained in:
parent
21986715b1
commit
99d190fac4
2 changed files with 18 additions and 6 deletions
|
@ -1,3 +1,11 @@
|
|||
2013-12-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf-eh-frame.c (cie_eq): Return false when initial_insn_length
|
||||
is too large.
|
||||
(cie_compute_hash): Don't exceed bounds of initial_instructions.
|
||||
(_bfd_elf_parse_eh_frame): Always set initial_insn_length, and
|
||||
save as much of insns to initial_instructions[] as will fit.
|
||||
|
||||
2013-12-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR binutils/16317
|
||||
|
|
|
@ -235,6 +235,7 @@ cie_eq (const void *e1, const void *e2)
|
|||
&& c1->lsda_encoding == c2->lsda_encoding
|
||||
&& c1->fde_encoding == c2->fde_encoding
|
||||
&& c1->initial_insn_length == c2->initial_insn_length
|
||||
&& c1->initial_insn_length <= sizeof (c1->initial_instructions)
|
||||
&& memcmp (c1->initial_instructions,
|
||||
c2->initial_instructions,
|
||||
c1->initial_insn_length) == 0)
|
||||
|
@ -254,6 +255,7 @@ static hashval_t
|
|||
cie_compute_hash (struct cie *c)
|
||||
{
|
||||
hashval_t h = 0;
|
||||
size_t len;
|
||||
h = iterative_hash_object (c->length, h);
|
||||
h = iterative_hash_object (c->version, h);
|
||||
h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
|
||||
|
@ -267,7 +269,10 @@ cie_compute_hash (struct cie *c)
|
|||
h = iterative_hash_object (c->lsda_encoding, h);
|
||||
h = iterative_hash_object (c->fde_encoding, h);
|
||||
h = iterative_hash_object (c->initial_insn_length, h);
|
||||
h = iterative_hash (c->initial_instructions, c->initial_insn_length, h);
|
||||
len = c->initial_insn_length;
|
||||
if (len > sizeof (c->initial_instructions))
|
||||
len = sizeof (c->initial_instructions);
|
||||
h = iterative_hash (c->initial_instructions, len, h);
|
||||
c->hash = h;
|
||||
return h;
|
||||
}
|
||||
|
@ -762,11 +767,10 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
|||
cie->fde_encoding = DW_EH_PE_absptr;
|
||||
|
||||
initial_insn_length = end - buf;
|
||||
if (initial_insn_length <= sizeof (cie->initial_instructions))
|
||||
{
|
||||
cie->initial_insn_length = initial_insn_length;
|
||||
memcpy (cie->initial_instructions, buf, initial_insn_length);
|
||||
}
|
||||
cie->initial_insn_length = initial_insn_length;
|
||||
memcpy (cie->initial_instructions, buf,
|
||||
initial_insn_length <= sizeof (cie->initial_instructions)
|
||||
? initial_insn_length : sizeof (cie->initial_instructions));
|
||||
insns = buf;
|
||||
buf += initial_insn_length;
|
||||
ENSURE_NO_RELOCS (buf);
|
||||
|
|
Loading…
Reference in a new issue