From: Sebastian Lackner Subject: winebuild: Do not access memory below ESP when restoring thread contexts. Message-Id: <54EBE424.8050309@fds-team.de> Date: Tue, 24 Feb 2015 03:38:28 +0100 Based on a patch by John Reiser. --- tools/winebuild/relay.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) From 2c9e4af027218dd83ee68bed4ff5ab277ce8948a Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 12 Feb 2015 11:09:34 +0100 Subject: winebuild: Do not access memory below ESP when restoring thread contexts. Based on a patch by John Reiser. --- tools/winebuild/relay.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c index cc7dd37..aa7158e 100644 --- a/tools/winebuild/relay.c +++ b/tools/winebuild/relay.c @@ -852,31 +852,48 @@ static void build_call_from_regs_x86(void) /* Restore the context structure */ - output( "2:\tpushl 0x94(%%ecx)\n"); /* SegEs */ + output( "2:\n" ); + + /* As soon as we have switched stacks the context structure could + * be invalid (when signal handlers are executed for example). Copy + * values on the target stack before changing ESP. */ + + output( "\tpushl 0xc8(%%ecx)\n" ); /* SegSs */ + output( "\tpopl %%es\n" ); + output( "\tmovl 0xc4(%%ecx),%%eax\n" ); /* Esp */ + output( "\tsubl $4*4, %%eax\n" ); + + output( "\tmovl 0xc0(%%ecx),%%edx\n" ); /* EFlags */ + output( "\t.byte 0x26\n\tmovl %%edx,3*4(%%eax)\n" ); + output( "\tmovl 0xbc(%%ecx),%%edx\n" ); /* SegCs */ + output( "\t.byte 0x26\n\tmovl %%edx,2*4(%%eax)\n" ); + output( "\tmovl 0xb8(%%ecx),%%edx\n" ); /* Eip */ + output( "\t.byte 0x26\n\tmovl %%edx,1*4(%%eax)\n" ); + output( "\tmovl 0xb0(%%ecx),%%edx\n" ); /* Eax */ + output( "\t.byte 0x26\n\tmovl %%edx,0*4(%%eax)\n" ); + + output( "\tpushl %%es\n" ); + output( "\tpushl 0x98(%%ecx)\n" ); /* SegDs */ + + output(" \tpushl 0x94(%%ecx)\n" ); /* SegEs */ output( "\tpopl %%es\n" ); output( "\tpushl 0x90(%%ecx)\n"); /* SegFs */ output( "\tpopl %%fs\n" ); output( "\tpushl 0x8c(%%ecx)\n"); /* SegGs */ output( "\tpopl %%gs\n" ); - output( "\tmovl 0x9c(%%ecx),%%edi\n"); /* Edi */ - output( "\tmovl 0xa0(%%ecx),%%esi\n"); /* Esi */ - output( "\tmovl 0xa8(%%ecx),%%edx\n"); /* Edx */ - output( "\tmovl 0xa4(%%ecx),%%ebx\n"); /* Ebx */ - output( "\tmovl 0xb0(%%ecx),%%eax\n"); /* Eax */ - output( "\tmovl 0xb4(%%ecx),%%ebp\n"); /* Ebp */ + output( "\tmovl 0x9c(%%ecx),%%edi\n" ); /* Edi */ + output( "\tmovl 0xa0(%%ecx),%%esi\n" ); /* Esi */ + output( "\tmovl 0xa4(%%ecx),%%ebx\n" ); /* Ebx */ + output( "\tmovl 0xa8(%%ecx),%%edx\n" ); /* Edx */ + output( "\tmovl 0xb4(%%ecx),%%ebp\n" ); /* Ebp */ + output( "\tmovl 0xac(%%ecx),%%ecx\n" ); /* Ecx */ - output( "\tpushl 0xc8(%%ecx)\n"); /* SegSs */ + output( "\tpopl %%ds\n" ); output( "\tpopl %%ss\n" ); - output( "\tmovl 0xc4(%%ecx),%%esp\n"); /* Esp */ + output( "\tmovl %%eax,%%esp\n" ); - output( "\tpushl 0xc0(%%ecx)\n"); /* EFlags */ - output( "\tpushl 0xbc(%%ecx)\n"); /* SegCs */ - output( "\tpushl 0xb8(%%ecx)\n"); /* Eip */ - output( "\tpushl 0x98(%%ecx)\n"); /* SegDs */ - output( "\tmovl 0xac(%%ecx),%%ecx\n"); /* Ecx */ - - output( "\tpopl %%ds\n" ); + output( "\tpopl %%eax\n" ); output( "\tiret\n" ); output_cfi( ".cfi_endproc" ); output_function_size( "__wine_call_from_regs" ); -- 2.2.2