1 From: Alan Modra <amodra@gmail.com>
2 Date: Fri, 20 Dec 2013 13:27:52 +0000 (+1030)
3 Subject: Don't segv on cie.initial_instructions[] overflow.
4 X-Git-Tag: gdb-7.7-release~148
5 X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff_plain;h=99d190fac4d2aab238cfc798dc5c28ab41456882
7 Don't segv on cie.initial_instructions[] overflow.
9 Don't attempt to merge CIEs with a larger number of insns than will
12 * elf-eh-frame.c (cie_eq): Return false when initial_insn_length
14 (cie_compute_hash): Don't exceed bounds of initial_instructions.
15 (_bfd_elf_parse_eh_frame): Always set initial_insn_length, and
16 save as much of insns to initial_instructions[] as will fit.
19 diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
20 index 832a991..4b6e8ea 100644
21 --- a/bfd/elf-eh-frame.c
22 +++ b/bfd/elf-eh-frame.c
23 @@ -235,6 +235,7 @@ cie_eq (const void *e1, const void *e2)
24 && c1->lsda_encoding == c2->lsda_encoding
25 && c1->fde_encoding == c2->fde_encoding
26 && c1->initial_insn_length == c2->initial_insn_length
27 + && c1->initial_insn_length <= sizeof (c1->initial_instructions)
28 && memcmp (c1->initial_instructions,
29 c2->initial_instructions,
30 c1->initial_insn_length) == 0)
31 @@ -254,6 +255,7 @@ static hashval_t
32 cie_compute_hash (struct cie *c)
36 h = iterative_hash_object (c->length, h);
37 h = iterative_hash_object (c->version, h);
38 h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
39 @@ -267,7 +269,10 @@ cie_compute_hash (struct cie *c)
40 h = iterative_hash_object (c->lsda_encoding, h);
41 h = iterative_hash_object (c->fde_encoding, h);
42 h = iterative_hash_object (c->initial_insn_length, h);
43 - h = iterative_hash (c->initial_instructions, c->initial_insn_length, h);
44 + len = c->initial_insn_length;
45 + if (len > sizeof (c->initial_instructions))
46 + len = sizeof (c->initial_instructions);
47 + h = iterative_hash (c->initial_instructions, len, h);
51 @@ -762,11 +767,10 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
52 cie->fde_encoding = DW_EH_PE_absptr;
54 initial_insn_length = end - buf;
55 - if (initial_insn_length <= sizeof (cie->initial_instructions))
57 - cie->initial_insn_length = initial_insn_length;
58 - memcpy (cie->initial_instructions, buf, initial_insn_length);
60 + cie->initial_insn_length = initial_insn_length;
61 + memcpy (cie->initial_instructions, buf,
62 + initial_insn_length <= sizeof (cie->initial_instructions)
63 + ? initial_insn_length : sizeof (cie->initial_instructions));
65 buf += initial_insn_length;
66 ENSURE_NO_RELOCS (buf);