PR ld/24338
* elf64-x86-64.c (elf_x86_64_relocate_section): Check for corrupt
input with bad relocation.
2019-03-15 H.J. Lu <hongjiu.lu@intel.com>
2019-03-15 H.J. Lu <hongjiu.lu@intel.com>
+ PR ld/24338
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Check for corrupt
+ input with bad relocation.
+
+22019-03-15 H.J. Lu <hongjiu.lu@intel.com>
+
* elf64-x86-64.c (elf_x86_64_relocate_section): Re-indent.
2019-03-14 Nick Clifton <nickc@redhat.com>
* elf64-x86-64.c (elf_x86_64_relocate_section): Re-indent.
2019-03-14 Nick Clifton <nickc@redhat.com>
{
if (contents[roff + 5] == 0xb8)
{
{
if (contents[roff + 5] == 0xb8)
{
+ if (roff < 3
+ || (roff - 3 + 22) > input_section->size)
+ {
+corrupt_input:
+ info->callbacks->einfo
+ (_("%F%P: corrupt input: %pB\n"),
+ input_bfd);
+ return FALSE;
+ }
memcpy (contents + roff - 3,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
"\0\0\0\0\x66\x0f\x1f\x44\0", 22);
largepic = 1;
}
else
memcpy (contents + roff - 3,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
"\0\0\0\0\x66\x0f\x1f\x44\0", 22);
largepic = 1;
}
else
- memcpy (contents + roff - 4,
- "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
- 16);
+ {
+ if (roff < 4
+ || (roff - 4 + 16) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + roff - 4,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
+ 16);
+ }
- memcpy (contents + roff - 3,
- "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
- 15);
+ {
+ if (roff < 3
+ || (roff - 3 + 15) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + roff - 3,
+ "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
+ 15);
+ }
bfd_put_32 (output_bfd,
elf_x86_64_tpoff (info, relocation),
contents + roff + 8 + largepic);
bfd_put_32 (output_bfd,
elf_x86_64_tpoff (info, relocation),
contents + roff + 8 + largepic);
+ if (roff < 3)
+ goto corrupt_input;
type = bfd_get_8 (input_bfd, contents + roff - 3);
val = bfd_get_8 (input_bfd, contents + roff - 1);
bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
type = bfd_get_8 (input_bfd, contents + roff - 3);
val = bfd_get_8 (input_bfd, contents + roff - 1);
bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
if (roff >= 3)
val = bfd_get_8 (input_bfd, contents + roff - 3);
else
if (roff >= 3)
val = bfd_get_8 (input_bfd, contents + roff - 3);
else
+ {
+ if (roff < 2)
+ goto corrupt_input;
+ val = 0;
+ }
type = bfd_get_8 (input_bfd, contents + roff - 2);
reg = bfd_get_8 (input_bfd, contents + roff - 1);
reg >>= 3;
type = bfd_get_8 (input_bfd, contents + roff - 2);
reg = bfd_get_8 (input_bfd, contents + roff - 1);
reg >>= 3;
{
/* movq */
if (val == 0x4c)
{
/* movq */
if (val == 0x4c)
- bfd_put_8 (output_bfd, 0x49,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x49,
+ contents + roff - 3);
+ }
else if (!ABI_64_P (output_bfd) && val == 0x44)
else if (!ABI_64_P (output_bfd) && val == 0x44)
- bfd_put_8 (output_bfd, 0x41,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x41,
+ contents + roff - 3);
+ }
bfd_put_8 (output_bfd, 0xc7,
contents + roff - 2);
bfd_put_8 (output_bfd, 0xc0 | reg,
bfd_put_8 (output_bfd, 0xc7,
contents + roff - 2);
bfd_put_8 (output_bfd, 0xc0 | reg,
/* addq/addl -> addq/addl - addressing with %rsp/%r12
is special */
if (val == 0x4c)
/* addq/addl -> addq/addl - addressing with %rsp/%r12
is special */
if (val == 0x4c)
- bfd_put_8 (output_bfd, 0x49,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x49,
+ contents + roff - 3);
+ }
else if (!ABI_64_P (output_bfd) && val == 0x44)
else if (!ABI_64_P (output_bfd) && val == 0x44)
- bfd_put_8 (output_bfd, 0x41,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x41,
+ contents + roff - 3);
+ }
bfd_put_8 (output_bfd, 0x81,
contents + roff - 2);
bfd_put_8 (output_bfd, 0xc0 | reg,
bfd_put_8 (output_bfd, 0x81,
contents + roff - 2);
bfd_put_8 (output_bfd, 0xc0 | reg,
{
/* addq/addl -> leaq/leal */
if (val == 0x4c)
{
/* addq/addl -> leaq/leal */
if (val == 0x4c)
- bfd_put_8 (output_bfd, 0x4d,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x4d,
+ contents + roff - 3);
+ }
else if (!ABI_64_P (output_bfd) && val == 0x44)
else if (!ABI_64_P (output_bfd) && val == 0x44)
- bfd_put_8 (output_bfd, 0x45,
- contents + roff - 3);
+ {
+ if (roff < 3)
+ goto corrupt_input;
+ bfd_put_8 (output_bfd, 0x45,
+ contents + roff - 3);
+ }
bfd_put_8 (output_bfd, 0x8d,
contents + roff - 2);
bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
bfd_put_8 (output_bfd, 0x8d,
contents + roff - 2);
bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
{
if (contents[roff + 5] == 0xb8)
{
{
if (contents[roff + 5] == 0xb8)
{
+ if (roff < 3
+ || (roff - 3 + 22) > input_section->size)
+ goto corrupt_input;
memcpy (contents + roff - 3,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
"\0\0\0\0\x66\x0f\x1f\x44\0", 22);
largepic = 1;
}
else
memcpy (contents + roff - 3,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
"\0\0\0\0\x66\x0f\x1f\x44\0", 22);
largepic = 1;
}
else
- memcpy (contents + roff - 4,
- "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
- 16);
+ {
+ if (roff < 4
+ || (roff - 4 + 16) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + roff - 4,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
+ 16);
+ }
- memcpy (contents + roff - 3,
- "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
- 15);
+ {
+ if (roff < 3
+ || (roff - 3 + 15) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + roff - 3,
+ "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
+ 15);
+ }
relocation = (htab->elf.sgot->output_section->vma
+ htab->elf.sgot->output_offset + off
relocation = (htab->elf.sgot->output_section->vma
+ htab->elf.sgot->output_offset + off
turn a leaq into a movq in the form we use it, it
suffices to change the second byte from 0x8d to
0x8b. */
turn a leaq into a movq in the form we use it, it
suffices to change the second byte from 0x8d to
0x8b. */
+ if (roff < 2)
+ goto corrupt_input;
bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
bfd_put_32 (output_bfd,
bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
bfd_put_32 (output_bfd,
BFD_ASSERT (r_type == R_X86_64_TPOFF32);
if (ABI_64_P (output_bfd))
{
BFD_ASSERT (r_type == R_X86_64_TPOFF32);
if (ABI_64_P (output_bfd))
{
+ if ((rel->r_offset + 5) >= input_section->size)
+ goto corrupt_input;
if (contents[rel->r_offset + 5] == 0xb8)
if (contents[rel->r_offset + 5] == 0xb8)
- memcpy (contents + rel->r_offset - 3,
- "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
- "\x64\x48\x8b\x04\x25\0\0\0", 22);
+ {
+ if (rel->r_offset < 3
+ || (rel->r_offset - 3 + 22) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
+ "\x64\x48\x8b\x04\x25\0\0\0", 22);
+ }
else if (contents[rel->r_offset + 4] == 0xff
|| contents[rel->r_offset + 4] == 0x67)
else if (contents[rel->r_offset + 4] == 0xff
|| contents[rel->r_offset + 4] == 0x67)
- memcpy (contents + rel->r_offset - 3,
- "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
- 13);
+ {
+ if (rel->r_offset < 3
+ || (rel->r_offset - 3 + 13) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
+ 13);
+
+ }
- memcpy (contents + rel->r_offset - 3,
- "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
+ {
+ if (rel->r_offset < 3
+ || (rel->r_offset - 3 + 12) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
+ }
+ if ((rel->r_offset + 4) >= input_section->size)
+ goto corrupt_input;
if (contents[rel->r_offset + 4] == 0xff)
if (contents[rel->r_offset + 4] == 0xff)
- memcpy (contents + rel->r_offset - 3,
- "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
- 13);
+ {
+ if (rel->r_offset < 3
+ || (rel->r_offset - 3 + 13) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
+ 13);
+ }
- memcpy (contents + rel->r_offset - 3,
- "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
+ {
+ if (rel->r_offset < 3
+ || (rel->r_offset - 3 + 12) > input_section->size)
+ goto corrupt_input;
+ memcpy (contents + rel->r_offset - 3,
+ "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
+ }
}
/* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
and R_X86_64_PLTOFF64. */
}
/* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
and R_X86_64_PLTOFF64. */