diff --git a/patches/ntdll-Stack_Fault/0001-ntdll-Commit-new-guard-pages-in-virtual_handle_stack.patch b/patches/ntdll-Stack_Fault/0001-ntdll-Commit-new-guard-pages-in-virtual_handle_stack.patch new file mode 100644 index 00000000..12476ba9 --- /dev/null +++ b/patches/ntdll-Stack_Fault/0001-ntdll-Commit-new-guard-pages-in-virtual_handle_stack.patch @@ -0,0 +1,26 @@ +From bedf1085f5229c85f990f3c0f41c62a47fef6c40 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 28 Nov 2015 21:28:26 +0100 +Subject: ntdll: Commit new guard pages in virtual_handle_stack_fault. (resend) + +Signed-off-by: Sebastian Lackner +--- + dlls/ntdll/virtual.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index 4d4bc3b..d6319d82 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -1550,7 +1550,7 @@ BOOL virtual_handle_stack_fault( void *addr ) + if ((char *)page >= (char *)NtCurrentTeb()->DeallocationStack + 2*page_size) + { + vprot = view->prot[((char *)page - page_size - (char *)view->base) >> page_shift]; +- VIRTUAL_SetProt( view, (char *)page - page_size, page_size, vprot | VPROT_GUARD ); ++ VIRTUAL_SetProt( view, (char *)page - page_size, page_size, vprot | VPROT_COMMITTED | VPROT_GUARD ); + } + ret = TRUE; + } +-- +2.6.2 + diff --git a/patches/ntdll-Stack_Fault/0001-ntdll-When-handling-stack-faults-also-commit-the-pag.patch b/patches/ntdll-Stack_Fault/0001-ntdll-When-handling-stack-faults-also-commit-the-pag.patch deleted file mode 100644 index 55c0bbc4..00000000 --- a/patches/ntdll-Stack_Fault/0001-ntdll-When-handling-stack-faults-also-commit-the-pag.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6235c2318a0180d0cc9b19aaab5f9369da09f68a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Tue, 25 Aug 2015 08:25:22 +0200 -Subject: ntdll: When handling stack faults also commit the page, instead of - just removing the guard page flag. - ---- - dlls/ntdll/virtual.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 8ece7e7..fc22029 100644 ---- a/dlls/ntdll/virtual.c -+++ b/dlls/ntdll/virtual.c -@@ -1606,6 +1606,7 @@ BOOL virtual_handle_stack_fault( void *addr ) - BYTE vprot = view->prot[((const char *)page - (const char *)view->base) >> page_shift]; - if (vprot & VPROT_GUARD) - { -+ if (!view->mapping) vprot |= VPROT_COMMITTED; /* FIXME */ - VIRTUAL_SetProt( view, page, page_size, vprot & ~VPROT_GUARD ); - NtCurrentTeb()->Tib.StackLimit = page; - if ((char *)page >= (char *)NtCurrentTeb()->DeallocationStack + 2*page_size) --- -2.5.0 - diff --git a/patches/ntdll-Stack_Fault/0002-kernel32-tests-Add-tests-for-committing-stack-guard-.patch b/patches/ntdll-Stack_Fault/0002-kernel32-tests-Add-tests-for-committing-stack-guard-.patch new file mode 100644 index 00000000..882e020f --- /dev/null +++ b/patches/ntdll-Stack_Fault/0002-kernel32-tests-Add-tests-for-committing-stack-guard-.patch @@ -0,0 +1,107 @@ +From 2a4736b15317859868a6d0133d60443325605703 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 28 Nov 2015 21:28:48 +0100 +Subject: kernel32/tests: Add tests for committing stack guard pages. (v2) + +Signed-off-by: Sebastian Lackner +--- + dlls/kernel32/tests/virtual.c | 76 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 76 insertions(+) + +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index e80ba38..e614bde 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -2048,6 +2048,81 @@ static void test_guard_page(void) + VirtualFree( base, 0, MEM_FREE ); + } + ++static DWORD WINAPI stack_commit_func( void *arg ) ++{ ++ volatile char *p = (char *)&p; ++ ++ /* trigger all guard pages, to ensure that the pages are committed */ ++ while (p >= (char *)pNtCurrentTeb()->DeallocationStack + 3 * 0x1000) ++ { ++ p[0] |= 0; ++ p -= 0x1000; ++ } ++ ++ ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg ); ++ return 42; ++} ++ ++static void test_stack_commit(void) ++{ ++ static const char code_call_on_stack[] = { ++ 0x55, /* pushl %ebp */ ++ 0x56, /* pushl %esi */ ++ 0x89, 0xe6, /* movl %esp,%esi */ ++ 0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */ ++ 0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */ ++ 0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */ ++ 0x83, 0xe0, 0xf0, /* andl $~15,%eax */ ++ 0x83, 0xe8, 0x0c, /* subl $12,%eax */ ++ 0x89, 0xc4, /* movl %eax,%esp */ ++ 0x52, /* pushl %edx */ ++ 0x31, 0xed, /* xorl %ebp,%ebp */ ++ 0xff, 0xd1, /* call *%ecx */ ++ 0x89, 0xf4, /* movl %esi,%esp */ ++ 0x5e, /* popl %esi */ ++ 0x5d, /* popl %ebp */ ++ 0xc2, 0x0c, 0x00 }; /* ret $12 */ ++ ++ DWORD (WINAPI *call_on_stack)( DWORD (WINAPI *func)(void *), void *arg, void *stack ); ++ void *old_stack, *old_stack_base, *old_stack_limit; ++ void *new_stack, *new_stack_base; ++ DWORD result; ++ ++ if (!pNtCurrentTeb) ++ { ++ win_skip( "NtCurrentTeb not supported\n" ); ++ return; ++ } ++ ++ call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); ++ ok( call_on_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() ); ++ memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) ); ++ ++ /* allocate a new stack, only the first guard page is committed */ ++ new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE ); ++ ok( new_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() ); ++ new_stack_base = (char *)new_stack + 0x400000; ++ VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD ); ++ ++ old_stack = pNtCurrentTeb()->DeallocationStack; ++ old_stack_base = pNtCurrentTeb()->Tib.StackBase; ++ old_stack_limit = pNtCurrentTeb()->Tib.StackLimit; ++ ++ pNtCurrentTeb()->DeallocationStack = new_stack; ++ pNtCurrentTeb()->Tib.StackBase = new_stack_base; ++ pNtCurrentTeb()->Tib.StackLimit = new_stack_base; ++ ++ result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, new_stack_base ); ++ ok( result == 42, "expected 42, got %u\n", result ); ++ ++ pNtCurrentTeb()->DeallocationStack = old_stack; ++ pNtCurrentTeb()->Tib.StackBase = old_stack_base; ++ pNtCurrentTeb()->Tib.StackLimit = old_stack_limit; ++ ++ VirtualFree( new_stack, 0, MEM_FREE ); ++ VirtualFree( call_on_stack, 0, MEM_FREE ); ++} ++ + DWORD num_execute_fault_calls; + + static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, +@@ -3772,6 +3847,7 @@ START_TEST(virtual) + test_write_watch(); + #ifdef __i386__ + test_guard_page(); ++ test_stack_commit(); + /* The following tests should be executed as a last step, and in exactly this + * order, since ATL thunk emulation cannot be enabled anymore on Windows. */ + test_atl_thunk_emulation( MEM_EXECUTE_OPTION_ENABLE ); +-- +2.6.2 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 973d73e3..9f55dd98 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -4310,12 +4310,14 @@ fi # Patchset ntdll-Stack_Fault # | # | Modified files: -# | * dlls/ntdll/virtual.c +# | * dlls/kernel32/tests/virtual.c, dlls/ntdll/virtual.c # | if test "$enable_ntdll_Stack_Fault" -eq 1; then - patch_apply ntdll-Stack_Fault/0001-ntdll-When-handling-stack-faults-also-commit-the-pag.patch + patch_apply ntdll-Stack_Fault/0001-ntdll-Commit-new-guard-pages-in-virtual_handle_stack.patch + patch_apply ntdll-Stack_Fault/0002-kernel32-tests-Add-tests-for-committing-stack-guard-.patch ( - echo '+ { "Sebastian Lackner", "ntdll: When handling stack faults also commit the page, instead of just removing the guard page flag.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Commit new guard pages in virtual_handle_stack_fault.", 1 },'; + echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for committing stack guard pages.", 2 },'; ) >> "$patchlist" fi diff --git a/staging/changelog b/staging/changelog index b9c34f0d..1855a364 100644 --- a/staging/changelog +++ b/staging/changelog @@ -1,4 +1,5 @@ wine-staging (1.8~rc2) UNRELEASED; urgency=low + * Updated patch to commit page when handling stack fault, and add tests. * Removed patch to revert "prepare GLresources before calling context_apply_fbo_state" commit. * Removed patch to set EAX to 0 in Basic_string_wchar_dtor (accepted