• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisionb23dc97fe237a1d9e850d7cbeee066183a00630b (tree)
Zeit2017-11-28 22:20:31
AutorNick Clifton <nickc@redh...>
CommiterNick Clifton

Log Message

Fix a memory access violation when attempting to parse a corrupt COFF binary with a relocation that points beyond the end of the section to be relocated.

PR 22506
* reloc.c (reloc_offset_in_range): Rename to
bfd_reloc_offset_in_range and export.
(bfd_perform_relocation): Rename function invocation.
(bfd_install_relocation): Likewise.
(bfd_final_link_relocate): Likewise.
* bfd-in2.h: Regenerate.
* coff-arm.c (coff_arm_reloc): Use bfd_reloc_offset_in_range.
* coff-i386.c (coff_i386_reloc): Likewise.
* coff-i860.c (coff_i860_reloc): Likewise.
* coff-m68k.c (mk68kcoff_common_addend_special_fn): Likewise.
* coff-m88k.c (m88k_special_reloc): Likewise.
* coff-mips.c (mips_reflo_reloc): Likewise.
* coff-x86_64.c (coff_amd64_reloc): Likewise.

Ändern Zusammenfassung

Diff

--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,20 @@
1+2017-11-28 Nick Clifton <nickc@redhat.com>
2+
3+ PR 22506
4+ * reloc.c (reloc_offset_in_range): Rename to
5+ bfd_reloc_offset_in_range and export.
6+ (bfd_perform_relocation): Rename function invocation.
7+ (bfd_install_relocation): Likewise.
8+ (bfd_final_link_relocate): Likewise.
9+ * bfd-in2.h: Regenerate.
10+ * coff-arm.c (coff_arm_reloc): Use bfd_reloc_offset_in_range.
11+ * coff-i386.c (coff_i386_reloc): Likewise.
12+ * coff-i860.c (coff_i860_reloc): Likewise.
13+ * coff-m68k.c (mk68kcoff_common_addend_special_fn): Likewise.
14+ * coff-m88k.c (m88k_special_reloc): Likewise.
15+ * coff-mips.c (mips_reflo_reloc): Likewise.
16+ * coff-x86_64.c (coff_amd64_reloc): Likewise.
17+
118 2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
219
320 * elf-m10300.c (mn10300_elf_check_relocs): Don't set
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2662,6 +2662,12 @@ bfd_reloc_status_type bfd_check_overflow
26622662 unsigned int addrsize,
26632663 bfd_vma relocation);
26642664
2665+bfd_boolean bfd_reloc_offset_in_range
2666+ (reloc_howto_type *howto,
2667+ bfd *abfd,
2668+ asection *section,
2669+ bfd_size_type offset);
2670+
26652671 bfd_reloc_status_type bfd_perform_relocation
26662672 (bfd *abfd,
26672673 arelent *reloc_entry,
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -109,41 +109,46 @@ coff_arm_reloc (bfd *abfd,
109109 x = ((x & ~howto->dst_mask) \
110110 | (((x & howto->src_mask) + diff) & howto->dst_mask))
111111
112- if (diff != 0)
113- {
114- reloc_howto_type *howto = reloc_entry->howto;
115- unsigned char *addr = (unsigned char *) data + reloc_entry->address;
112+ if (diff != 0)
113+ {
114+ reloc_howto_type *howto = reloc_entry->howto;
115+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
116116
117- switch (howto->size)
118- {
119- case 0:
120- {
121- char x = bfd_get_8 (abfd, addr);
122- DOIT (x);
123- bfd_put_8 (abfd, x, addr);
124- }
125- break;
117+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
118+ reloc_entry->address
119+ * bfd_octets_per_byte (abfd)))
120+ return bfd_reloc_outofrange;
126121
127- case 1:
128- {
129- short x = bfd_get_16 (abfd, addr);
130- DOIT (x);
131- bfd_put_16 (abfd, (bfd_vma) x, addr);
132- }
133- break;
122+ switch (howto->size)
123+ {
124+ case 0:
125+ {
126+ char x = bfd_get_8 (abfd, addr);
127+ DOIT (x);
128+ bfd_put_8 (abfd, x, addr);
129+ }
130+ break;
134131
135- case 2:
136- {
137- long x = bfd_get_32 (abfd, addr);
138- DOIT (x);
139- bfd_put_32 (abfd, (bfd_vma) x, addr);
140- }
141- break;
132+ case 1:
133+ {
134+ short x = bfd_get_16 (abfd, addr);
135+ DOIT (x);
136+ bfd_put_16 (abfd, (bfd_vma) x, addr);
137+ }
138+ break;
142139
143- default:
144- abort ();
140+ case 2:
141+ {
142+ long x = bfd_get_32 (abfd, addr);
143+ DOIT (x);
144+ bfd_put_32 (abfd, (bfd_vma) x, addr);
145145 }
146- }
146+ break;
147+
148+ default:
149+ abort ();
150+ }
151+ }
147152
148153 /* Now let bfd_perform_relocation finish everything up. */
149154 return bfd_reloc_continue;
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -144,6 +144,11 @@ coff_i386_reloc (bfd *abfd,
144144 reloc_howto_type *howto = reloc_entry->howto;
145145 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
146146
147+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
148+ reloc_entry->address
149+ * bfd_octets_per_byte (abfd)))
150+ return bfd_reloc_outofrange;
151+
147152 switch (howto->size)
148153 {
149154 case 0:
--- a/bfd/coff-i860.c
+++ b/bfd/coff-i860.c
@@ -95,6 +95,11 @@ coff_i860_reloc (bfd *abfd,
9595 reloc_howto_type *howto = reloc_entry->howto;
9696 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
9797
98+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
99+ reloc_entry->address
100+ * bfd_octets_per_byte (abfd)))
101+ return bfd_reloc_outofrange;
102+
98103 switch (howto->size)
99104 {
100105 case 0:
--- a/bfd/coff-m68k.c
+++ b/bfd/coff-m68k.c
@@ -305,6 +305,11 @@ m68kcoff_common_addend_special_fn (bfd *abfd,
305305 reloc_howto_type *howto = reloc_entry->howto;
306306 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
307307
308+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
309+ reloc_entry->address
310+ * bfd_octets_per_byte (abfd)))
311+ return bfd_reloc_outofrange;
312+
308313 switch (howto->size)
309314 {
310315 case 0:
--- a/bfd/coff-m88k.c
+++ b/bfd/coff-m88k.c
@@ -72,10 +72,17 @@ m88k_special_reloc (bfd *abfd,
7272 {
7373 bfd_vma output_base = 0;
7474 bfd_vma addr = reloc_entry->address;
75- bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
75+ bfd_vma x;
7676 asection *reloc_target_output_section;
7777 long relocation = 0;
7878
79+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
80+ reloc_entry->address
81+ * bfd_octets_per_byte (abfd)))
82+ return bfd_reloc_outofrange;
83+
84+ x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
85+
7986 /* Work out which section the relocation is targeted at and the
8087 initial relocation command value. */
8188
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -504,6 +504,12 @@ mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
504504 unsigned long vallo;
505505 struct mips_hi *next;
506506
507+ if (! bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
508+ input_section,
509+ reloc_entry->address
510+ * bfd_octets_per_byte (abfd)))
511+ return bfd_reloc_outofrange;
512+
507513 /* Do the REFHI relocation. Note that we actually don't
508514 need to know anything about the REFLO itself, except
509515 where to find the low 16 bits of the addend needed by the
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -142,17 +142,11 @@ coff_amd64_reloc (bfd *abfd,
142142 {
143143 reloc_howto_type *howto = reloc_entry->howto;
144144 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
145-
146- /* FIXME: We do not have an end address for data, so we cannot
147- accurately range check any addresses computed against it.
148- cf: PR binutils/17512: file: 1085-1761-0.004.
149- For now we do the best that we can. */
150- if (addr < (unsigned char *) data
151- || addr > ((unsigned char *) data) + input_section->size)
152- {
153- bfd_set_error (bfd_error_bad_value);
154- return bfd_reloc_notsupported;
155- }
145+
146+ if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
147+ reloc_entry->address
148+ * bfd_octets_per_byte (abfd)))
149+ return bfd_reloc_outofrange;
156150
157151 switch (howto->size)
158152 {
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -540,12 +540,31 @@ bfd_check_overflow (enum complain_overflow how,
540540 return flag;
541541 }
542542
543+/*
544+FUNCTION
545+ bfd_reloc_offset_in_range
546+
547+SYNOPSIS
548+ bfd_boolean bfd_reloc_offset_in_range
549+ (reloc_howto_type *howto,
550+ bfd *abfd,
551+ asection *section,
552+ bfd_size_type offset);
553+
554+DESCRIPTION
555+ Returns TRUE if the reloc described by @var{HOWTO} can be
556+ applied at @var{OFFSET} octets in @var{SECTION}.
557+
558+*/
559+
543560 /* HOWTO describes a relocation, at offset OCTET. Return whether the
544561 relocation field is within SECTION of ABFD. */
545562
546-static bfd_boolean
547-reloc_offset_in_range (reloc_howto_type *howto, bfd *abfd,
548- asection *section, bfd_size_type octet)
563+bfd_boolean
564+bfd_reloc_offset_in_range (reloc_howto_type *howto,
565+ bfd *abfd,
566+ asection *section,
567+ bfd_size_type octet)
549568 {
550569 bfd_size_type octet_end = bfd_get_section_limit_octets (abfd, section);
551570 bfd_size_type reloc_size = bfd_get_reloc_size (howto);
@@ -619,6 +638,11 @@ bfd_perform_relocation (bfd *abfd,
619638 if (howto && howto->special_function)
620639 {
621640 bfd_reloc_status_type cont;
641+
642+ /* Note - we do not call bfd_reloc_offset_in_range here as the
643+ reloc_entry->address field might actually be valid for the
644+ backend concerned. It is up to the special_function itself
645+ to call bfd_reloc_offset_in_range if needed. */
622646 cont = howto->special_function (abfd, reloc_entry, symbol, data,
623647 input_section, output_bfd,
624648 error_message);
@@ -639,7 +663,7 @@ bfd_perform_relocation (bfd *abfd,
639663
640664 /* Is the address of the relocation really within the section? */
641665 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
642- if (!reloc_offset_in_range (howto, abfd, input_section, octets))
666+ if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
643667 return bfd_reloc_outofrange;
644668
645669 /* Work out which section the relocation is targeted at and the
@@ -1005,6 +1029,10 @@ bfd_install_relocation (bfd *abfd,
10051029 {
10061030 bfd_reloc_status_type cont;
10071031
1032+ /* Note - we do not call bfd_reloc_offset_in_range here as the
1033+ reloc_entry->address field might actually be valid for the
1034+ backend concerned. It is up to the special_function itself
1035+ to call bfd_reloc_offset_in_range if needed. */
10081036 /* XXX - The special_function calls haven't been fixed up to deal
10091037 with creating new relocations and section contents. */
10101038 cont = howto->special_function (abfd, reloc_entry, symbol,
@@ -1027,7 +1055,7 @@ bfd_install_relocation (bfd *abfd,
10271055
10281056 /* Is the address of the relocation really within the section? */
10291057 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
1030- if (!reloc_offset_in_range (howto, abfd, input_section, octets))
1058+ if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
10311059 return bfd_reloc_outofrange;
10321060
10331061 /* Work out which section the relocation is targeted at and the
@@ -1365,7 +1393,7 @@ _bfd_final_link_relocate (reloc_howto_type *howto,
13651393 bfd_size_type octets = address * bfd_octets_per_byte (input_bfd);
13661394
13671395 /* Sanity check the address. */
1368- if (!reloc_offset_in_range (howto, input_bfd, input_section, octets))
1396+ if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, octets))
13691397 return bfd_reloc_outofrange;
13701398
13711399 /* This function assumes that we are dealing with a basic relocation