aboutsummaryrefslogtreecommitdiff
path: root/bfd/pei-x86_64.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2019-08-22 14:37:03 +0100
committerNick Clifton <nickc@redhat.com>2019-08-22 14:37:03 +0100
commit03da31c6764c1bca9b0b0529344a8ea933c825ea (patch)
treeaa83f97d5a4ef3dc0bb96007f3a2eb1c90945950 /bfd/pei-x86_64.c
parent93d6a337d528bcb7519f0cdb931b3ca0e1c943a9 (diff)
downloadfsf-binutils-gdb-03da31c6764c1bca9b0b0529344a8ea933c825ea.zip
fsf-binutils-gdb-03da31c6764c1bca9b0b0529344a8ea933c825ea.tar.gz
fsf-binutils-gdb-03da31c6764c1bca9b0b0529344a8ea933c825ea.tar.bz2
Fix an illegal memory access when dumping corrupt x86_64 PE unwind data.
PR 24922 * pei-x86_64.c (pex64_xdata_print_uwd_codes): Add checks before reading data from extra records.
Diffstat (limited to 'bfd/pei-x86_64.c')
-rw-r--r--bfd/pei-x86_64.c71
1 files changed, 62 insertions, 9 deletions
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
index 8a88827..2588e6c 100644
--- a/bfd/pei-x86_64.c
+++ b/bfd/pei-x86_64.c
@@ -228,27 +228,41 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
int unexpected = FALSE;
fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]);
+
switch (PEX64_UNWCODE_CODE (dta[1]))
{
case UWOP_PUSH_NONVOL:
fprintf (file, "push %s", pex_regs[info]);
break;
+
case UWOP_ALLOC_LARGE:
if (info == 0)
{
- tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ if (dta + 4 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_16 (abfd, dta + 2) * 8;
i++;
}
else
{
- tmp = bfd_get_32 (abfd, &dta[2]);
+ if (dta + 6 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_32 (abfd, dta + 2);
i += 2;
}
fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
break;
+
case UWOP_ALLOC_SMALL:
fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
break;
+
case UWOP_SET_FPREG:
/* According to the documentation, info field is unused. */
fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
@@ -257,22 +271,40 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
unexpected = ui->FrameRegister == 0;
save_allowed = FALSE;
break;
+
case UWOP_SAVE_NONVOL:
- tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ if (dta + 4 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_16 (abfd, dta + 2) * 8;
i++;
fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
unexpected = !save_allowed;
break;
+
case UWOP_SAVE_NONVOL_FAR:
- tmp = bfd_get_32 (abfd, &dta[2]);
+ if (dta + 6 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_32 (abfd, dta + 2);
i += 2;
fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
unexpected = !save_allowed;
break;
+
case UWOP_SAVE_XMM:
if (ui->Version == 1)
{
- tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ if (dta + 4 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_16 (abfd, dta + 2) * 8;
i++;
fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
unexpected = !save_allowed;
@@ -283,24 +315,43 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
unexpected = TRUE;
}
break;
+
case UWOP_SAVE_XMM_FAR:
- tmp = bfd_get_32 (abfd, &dta[2]) * 8;
+ if (dta + 6 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_32 (abfd, dta + 2) * 8;
i += 2;
fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
unexpected = !save_allowed;
break;
+
case UWOP_SAVE_XMM128:
- tmp = bfd_get_16 (abfd, &dta[2]) * 16;
+ if (dta + 4 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_16 (abfd, dta + 2) * 16;
i++;
fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
unexpected = !save_allowed;
break;
+
case UWOP_SAVE_XMM128_FAR:
- tmp = bfd_get_32 (abfd, &dta[2]) * 16;
+ if (dta + 6 > ui->rawUnwindCodesEnd)
+ {
+ fprintf (file, _("warning: corrupt unwind data\n"));
+ return;
+ }
+ tmp = bfd_get_32 (abfd, dta + 2) * 16;
i += 2;
fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
unexpected = !save_allowed;
break;
+
case UWOP_PUSH_MACHFRAME:
fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
if (info == 0)
@@ -310,11 +361,13 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
else
fprintf (file, ", unknown(%u))", info);
break;
+
default:
/* PR 17512: file: 2245-7442-0.004. */
fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
break;
- }
+ }
+
if (unexpected)
fprintf (file, " [Unexpected!]");
fputc ('\n', file);