From d661521305e4e7169c0fd923e1b1c49a0618c7d5 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sun, 15 May 2016 16:31:51 +0200 Subject: [PATCH] ntdll-WRITECOPY: Do not mark tests as fixed. The code is not active unless a special environment variable is set. --- ...andle-PAGE_WRITECOPY-protection.-try.patch | 76 ++++++++++--------- ...e-true-WRITECOPY-protection-when-a-s.patch | 54 ------------- patches/patchinstall.sh | 8 +- 3 files changed, 42 insertions(+), 96 deletions(-) delete mode 100644 patches/ntdll-WRITECOPY/0005-ntdll-Only-enable-true-WRITECOPY-protection-when-a-s.patch diff --git a/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch b/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch index 6fd36ec1..08b2a4b5 100644 --- a/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch +++ b/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch @@ -1,51 +1,53 @@ -From a1743661a00045d656892c8de7f6f0324dcd1404 Mon Sep 17 00:00:00 2001 +From 87487f38ad629bd54983bcef11a8a205e9da985a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sat, 4 Oct 2014 02:56:08 +0200 +Date: Sat, 4 Oct 2014 03:22:09 +0200 Subject: ntdll: Properly handle PAGE_WRITECOPY protection. (try 5) +For now, only enable it when a special environment variable is set. --- - dlls/kernel32/tests/virtual.c | 8 ++------ - dlls/ntdll/virtual.c | 26 +++++++++++++++++++------- - 2 files changed, 21 insertions(+), 13 deletions(-) + dlls/ntdll/virtual.c | 47 ++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 40 insertions(+), 7 deletions(-) -diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c -index a3ae5e6..3b167d2 100644 ---- a/dlls/kernel32/tests/virtual.c -+++ b/dlls/kernel32/tests/virtual.c -@@ -3278,9 +3278,7 @@ static void test_CreateFileMapping_protection(void) - SetLastError(0xdeadbeef); - ret = VirtualQuery(base, &info, sizeof(info)); - ok(ret, "VirtualQuery failed %d\n", GetLastError()); -- /* FIXME: remove the condition below once Wine is fixed */ -- todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == PAGE_EXECUTE_WRITECOPY) -- ok(info.Protect == td[i].prot_after_write, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_after_write); -+ ok(info.Protect == td[i].prot_after_write, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_after_write); - } - } - else -@@ -3294,9 +3292,7 @@ static void test_CreateFileMapping_protection(void) - SetLastError(0xdeadbeef); - ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot); - ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError()); -- /* FIXME: remove the condition below once Wine is fixed */ -- todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == PAGE_EXECUTE_WRITECOPY) -- ok(old_prot == td[i].prot_after_write, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_after_write); -+ ok(old_prot == td[i].prot_after_write, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_after_write); - } - - UnmapViewOfFile(base); diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index caf2b70..728b857 100644 +index 5c43d26..bf5bc22 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c -@@ -178,8 +178,13 @@ static int VIRTUAL_GetUnixProt( BYTE vprot ) +@@ -165,6 +165,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot ) + return buffer; + } + ++/* This might look like a hack, but it actually isn't - the 'experimental' version ++ * is correct, but it already has revealed a couple of additional Wine bugs, which ++ * were not triggered before, and there are probably some more. ++ * To avoid breaking Wine for everyone, the new correct implementation has to be ++ * manually enabled, until it is tested a bit more. */ ++static inline BOOL experimental_WRITECOPY( void ) ++{ ++ static int enabled = -1; ++ if (enabled == -1) ++ { ++ const char *str = getenv("STAGING_WRITECOPY"); ++ enabled = str && (atoi(str) != 0); ++ } ++ return enabled; ++} + + /*********************************************************************** + * VIRTUAL_GetUnixProt +@@ -178,8 +193,19 @@ static int VIRTUAL_GetUnixProt( BYTE vprot ) { if (vprot & VPROT_READ) prot |= PROT_READ; if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ; - if (vprot & VPROT_WRITECOPY) prot |= PROT_WRITE | PROT_READ; if (vprot & VPROT_EXEC) prot |= PROT_EXEC | PROT_READ; +#if defined(__i386__) -+ if (vprot & VPROT_WRITECOPY) prot = (prot & ~PROT_WRITE) | PROT_READ; ++ if (vprot & VPROT_WRITECOPY) ++ { ++ if (experimental_WRITECOPY()) ++ prot = (prot & ~PROT_WRITE) | PROT_READ; ++ else ++ prot |= PROT_WRITE | PROT_READ; ++ } +#else + /* FIXME: Architecture needs implementation of signal_init_early. */ + if (vprot & VPROT_WRITECOPY) prot |= PROT_WRITE | PROT_READ; @@ -53,7 +55,7 @@ index caf2b70..728b857 100644 if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE; } if (!prot) prot = PROT_NONE; -@@ -1488,13 +1493,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) +@@ -1488,13 +1514,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) { void *page = ROUND_ADDR( addr, page_mask ); BYTE *vprot = &view->prot[((const char *)page - (const char *)view->base) >> page_shift]; @@ -74,7 +76,7 @@ index caf2b70..728b857 100644 /* ignore fault if page is writable now */ if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS; } -@@ -1703,14 +1713,16 @@ SIZE_T CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SI +@@ -1697,14 +1728,16 @@ SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_ * exception. Similar to virtual_handle_fault. */ if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE)) { @@ -96,5 +98,5 @@ index caf2b70..728b857 100644 if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE)) break; -- -2.7.1 +2.8.0 diff --git a/patches/ntdll-WRITECOPY/0005-ntdll-Only-enable-true-WRITECOPY-protection-when-a-s.patch b/patches/ntdll-WRITECOPY/0005-ntdll-Only-enable-true-WRITECOPY-protection-when-a-s.patch deleted file mode 100644 index e3953797..00000000 --- a/patches/ntdll-WRITECOPY/0005-ntdll-Only-enable-true-WRITECOPY-protection-when-a-s.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 3d29cd7c6feabae6c5ae5941f49c663b1fb78ab8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sat, 4 Oct 2014 03:22:09 +0200 -Subject: ntdll: Only enable true WRITECOPY protection when a special - environment variable is set. - ---- - dlls/ntdll/virtual.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 36d8836..0c7ae29 100644 ---- a/dlls/ntdll/virtual.c -+++ b/dlls/ntdll/virtual.c -@@ -166,6 +166,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot ) - return buffer; - } - -+/* This might look like a hack, but it actually isn't - the 'experimental' version -+ * is correct, but it already has revealed a couple of additional Wine bugs, which -+ * were not triggered before, and there are probably some more. -+ * To avoid breaking Wine for everyone, the new correct implementation has to be -+ * manually enabled, until it is tested a bit more. */ -+static inline BOOL experimental_WRITECOPY( void ) -+{ -+ static int enabled = -1; -+ if (enabled == -1) -+ { -+ const char *str = getenv("STAGING_WRITECOPY"); -+ enabled = str && (atoi(str) != 0); -+ } -+ return enabled; -+} - - /*********************************************************************** - * VIRTUAL_GetUnixProt -@@ -181,7 +196,13 @@ static int VIRTUAL_GetUnixProt( BYTE vprot ) - if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ; - if (vprot & VPROT_EXEC) prot |= PROT_EXEC | PROT_READ; - #if defined(__i386__) -- if (vprot & VPROT_WRITECOPY) prot = (prot & ~PROT_WRITE) | PROT_READ; -+ if (vprot & VPROT_WRITECOPY) -+ { -+ if (experimental_WRITECOPY()) -+ prot = (prot & ~PROT_WRITE) | PROT_READ; -+ else -+ prot |= PROT_WRITE | PROT_READ; -+ } - #else - /* FIXME: Architecture needs implementation of signal_init_early. */ - if (vprot & VPROT_WRITECOPY) prot |= PROT_WRITE | PROT_READ; --- -2.2.1 - diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 99d363c1..ee9f7686 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -5200,22 +5200,20 @@ fi # | * [#35561] MSYS2 expects correct handling of WRITECOPY memory protection # | # | Modified files: -# | * dlls/advapi32/crypt.c, dlls/advapi32/tests/security.c, dlls/kernel32/tests/virtual.c, dlls/ntdll/ntdll_misc.h, -# | dlls/ntdll/server.c, dlls/ntdll/signal_arm.c, dlls/ntdll/signal_arm64.c, dlls/ntdll/signal_i386.c, -# | dlls/ntdll/signal_powerpc.c, dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c +# | * dlls/advapi32/crypt.c, dlls/advapi32/tests/security.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c, +# | dlls/ntdll/signal_arm.c, dlls/ntdll/signal_arm64.c, dlls/ntdll/signal_i386.c, dlls/ntdll/signal_powerpc.c, +# | dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c # | if test "$enable_ntdll_WRITECOPY" -eq 1; then patch_apply ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch patch_apply ntdll-WRITECOPY/0002-advapi-Trigger-write-watches-before-passing-userdata.patch patch_apply ntdll-WRITECOPY/0003-ntdll-Setup-a-temporary-signal-handler-during-proces.patch patch_apply ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch - patch_apply ntdll-WRITECOPY/0005-ntdll-Only-enable-true-WRITECOPY-protection-when-a-s.patch ( echo '+ { "Sebastian Lackner", "ntdll: Trigger write watches before passing userdata pointer to wait_reply.", 1 },'; echo '+ { "Sebastian Lackner", "advapi: Trigger write watches before passing userdata pointer to read syscall.", 1 },'; echo '+ { "Michael Müller", "ntdll: Setup a temporary signal handler during process startup to handle page faults.", 2 },'; echo '+ { "Michael Müller", "ntdll: Properly handle PAGE_WRITECOPY protection.", 5 },'; - echo '+ { "Michael Müller", "ntdll: Only enable true WRITECOPY protection when a special environment variable is set.", 1 },'; ) >> "$patchlist" fi