From 094f2d8d0cd09ba4235596e914e03f318da1df51 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 25 Sep 2017 13:15:02 +0200 Subject: [PATCH] Rebase against 44cb0afb2571984bda8ca1fa084a50c1fc04ac71. --- ...d-implicit-cast-of-interface-pointer.patch | 25 +++ .../0005-include-Add-dxva.h-header-file.patch | 14 +- ...a2-tests-Add-tests-for-dxva2-decoder.patch | 6 +- ...plementation-of-MPEG2-decoder-using-.patch | 14 +- ...0001-ntdll-Fix-holes-in-ELF-mappings.patch | 64 ++++--- ...ead-to-update-user_shared_data-time-.patch | 58 +++---- ...ite-watches-before-passing-userdata-.patch | 24 +-- ...andle-PAGE_WRITECOPY-protection.-try.patch | 104 ++++++----- patches/ntdll-WRITECOPY/definition | 2 +- ...-conditions-with-write-watches-in-Nt.patch | 112 ------------ patches/ntdll-WriteWatches/definition | 3 - patches/patchinstall.sh | 76 +++----- ...e_uninterrupted_-read-write-_memory-.patch | 162 ------------------ ...e-conditions-of-async-WSARecv-operat.patch | 133 ++++++++++---- 14 files changed, 302 insertions(+), 495 deletions(-) create mode 100644 patches/Compiler_Warnings/0033-evr-Avoid-implicit-cast-of-interface-pointer.patch delete mode 100644 patches/ntdll-WriteWatches/0001-ntdll-Avoid-race-conditions-with-write-watches-in-Nt.patch delete mode 100644 patches/ntdll-WriteWatches/definition delete mode 100644 patches/ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch diff --git a/patches/Compiler_Warnings/0033-evr-Avoid-implicit-cast-of-interface-pointer.patch b/patches/Compiler_Warnings/0033-evr-Avoid-implicit-cast-of-interface-pointer.patch new file mode 100644 index 00000000..5ae4c4b5 --- /dev/null +++ b/patches/Compiler_Warnings/0033-evr-Avoid-implicit-cast-of-interface-pointer.patch @@ -0,0 +1,25 @@ +From b4586e37df817f205c8bebe319b4765dea5c62d5 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 24 Sep 2017 19:21:06 +0200 +Subject: evr: Avoid implicit cast of interface pointer. + +--- + dlls/evr/evr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/evr/evr.c b/dlls/evr/evr.c +index c2d2933211e..5533f38a649 100644 +--- a/dlls/evr/evr.c ++++ b/dlls/evr/evr.c +@@ -136,7 +136,7 @@ static const IUnknownVtbl evr_inner_vtbl = + + static inline evr_filter *impl_from_IBaseFilter(IBaseFilter *iface) + { +- return CONTAINING_RECORD(iface, evr_filter, filter); ++ return CONTAINING_RECORD(iface, evr_filter, filter.IBaseFilter_iface); + } + + static HRESULT WINAPI filter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) +-- +2.14.1 + diff --git a/patches/dxva2-Video_Decoder/0005-include-Add-dxva.h-header-file.patch b/patches/dxva2-Video_Decoder/0005-include-Add-dxva.h-header-file.patch index b1c648ff..2130e33a 100644 --- a/patches/dxva2-Video_Decoder/0005-include-Add-dxva.h-header-file.patch +++ b/patches/dxva2-Video_Decoder/0005-include-Add-dxva.h-header-file.patch @@ -1,4 +1,4 @@ -From 08d0f4fee02fa6c01308461b3cecea842439fd15 Mon Sep 17 00:00:00 2001 +From b705357e89463258880e8f7605a33285d5eb0530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 22 Feb 2015 01:10:21 +0100 Subject: include: Add dxva.h header file. @@ -10,20 +10,20 @@ Subject: include: Add dxva.h header file. create mode 100644 include/dxva.h diff --git a/include/Makefile.in b/include/Makefile.in -index 682072c..94a2b84 100644 +index fd52a5f65a0..31d7fff6c2f 100644 --- a/include/Makefile.in +++ b/include/Makefile.in -@@ -306,6 +306,7 @@ HEADER_SRCS = \ +@@ -374,6 +374,7 @@ HEADER_SRCS = \ + dxerr8.h \ + dxerr9.h \ dxfile.h \ - dxgiformat.h \ - dxgitype.h \ + dxva.h \ errorrep.h \ errors.h \ evcode.h \ diff --git a/include/dxva.h b/include/dxva.h new file mode 100644 -index 0000000..e311488 +index 00000000000..e311488775a --- /dev/null +++ b/include/dxva.h @@ -0,0 +1,215 @@ @@ -243,5 +243,5 @@ index 0000000..e311488 + +#endif /* __WINE_DXVA_H */ -- -2.6.2 +2.14.1 diff --git a/patches/dxva2-Video_Decoder/0006-dxva2-tests-Add-tests-for-dxva2-decoder.patch b/patches/dxva2-Video_Decoder/0006-dxva2-tests-Add-tests-for-dxva2-decoder.patch index 38f8ea0f..f6dc51cf 100644 --- a/patches/dxva2-Video_Decoder/0006-dxva2-tests-Add-tests-for-dxva2-decoder.patch +++ b/patches/dxva2-Video_Decoder/0006-dxva2-tests-Add-tests-for-dxva2-decoder.patch @@ -1,4 +1,4 @@ -From 8cb1d2c62815a03ded72eebeb9ac0080f8e382a0 Mon Sep 17 00:00:00 2001 +From 0fdcec4ed315b9633390d19258cff7bb209a5fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 22 Feb 2015 01:21:18 +0100 Subject: dxva2/tests: Add tests for dxva2 decoder. @@ -12,7 +12,7 @@ Subject: dxva2/tests: Add tests for dxva2 decoder. create mode 100644 dlls/dxva2/tests/dxva2.c diff --git a/configure.ac b/configure.ac -index edeeb0de6f9..fb65b3b357a 100644 +index faa7791ecb5..8dae7719327 100644 --- a/configure.ac +++ b/configure.ac @@ -3120,6 +3120,7 @@ WINE_CONFIG_DLL(dxgi,,[implib]) @@ -21,7 +21,7 @@ index edeeb0de6f9..fb65b3b357a 100644 WINE_CONFIG_DLL(dxva2) +WINE_CONFIG_TEST(dlls/dxva2/tests) WINE_CONFIG_DLL(esent) - WINE_CONFIG_DLL(evr) + WINE_CONFIG_DLL(evr,,[clean]) WINE_CONFIG_TEST(dlls/evr/tests) diff --git a/dlls/dxva2/tests/Makefile.in b/dlls/dxva2/tests/Makefile.in new file mode 100644 diff --git a/patches/dxva2-Video_Decoder/0007-dxva2-Initial-implementation-of-MPEG2-decoder-using-.patch b/patches/dxva2-Video_Decoder/0007-dxva2-Initial-implementation-of-MPEG2-decoder-using-.patch index d4fc65ad..93955911 100644 --- a/patches/dxva2-Video_Decoder/0007-dxva2-Initial-implementation-of-MPEG2-decoder-using-.patch +++ b/patches/dxva2-Video_Decoder/0007-dxva2-Initial-implementation-of-MPEG2-decoder-using-.patch @@ -1,4 +1,4 @@ -From 91d1ab12e88ed9013ca63589f50b635ba9ed46b1 Mon Sep 17 00:00:00 2001 +From 1bef4fd44c776f823f87c1b1014d452888c1e8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 22 Feb 2015 01:25:20 +0100 Subject: dxva2: Initial implementation of MPEG2 decoder using vaapi backend. @@ -21,10 +21,10 @@ Subject: dxva2: Initial implementation of MPEG2 decoder using vaapi backend. create mode 100644 dlls/dxva2/vaapi.c diff --git a/configure.ac b/configure.ac -index c94403b1a9b..52604e2bf35 100644 +index 8dae7719327..9ab6cfafb1d 100644 --- a/configure.ac +++ b/configure.ac -@@ -101,6 +101,8 @@ AC_ARG_WITH(xxf86vm, AS_HELP_STRING([--without-xxf86vm],[do not use XFree vide +@@ -103,6 +103,8 @@ AC_ARG_WITH(xxf86vm, AS_HELP_STRING([--without-xxf86vm],[do not use XFree vide [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_xf86vmode_h=no; ac_cv_header_X11_extensions_xf86vmproto_h=no; fi]) AC_ARG_WITH(zlib, AS_HELP_STRING([--without-zlib],[do not use Zlib (data compression)]), [if test "x$withval" = "xno"; then ac_cv_header_zlib_h=no; fi]) @@ -33,7 +33,7 @@ index c94403b1a9b..52604e2bf35 100644 AC_ARG_WITH(wine-tools,AS_HELP_STRING([--with-wine-tools=DIR],[use Wine tools from directory DIR])) AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine in DIR for a Wow64 build])) -@@ -1157,6 +1159,20 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c +@@ -1186,6 +1188,20 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c WINE_WARNING_WITH(opengl,[test -n "$opengl_msg"],[$opengl_msg OpenGL and Direct3D won't be supported.]) @@ -54,7 +54,7 @@ index c94403b1a9b..52604e2bf35 100644 CPPFLAGS="$ac_save_CPPFLAGS" else X_CFLAGS="" -@@ -3012,7 +3028,7 @@ WINE_CONFIG_LIB(dxerr9) +@@ -3119,7 +3135,7 @@ WINE_CONFIG_LIB(dxerr9) WINE_CONFIG_DLL(dxgi,,[implib]) WINE_CONFIG_TEST(dlls/dxgi/tests) WINE_CONFIG_LIB(dxguid) @@ -62,7 +62,7 @@ index c94403b1a9b..52604e2bf35 100644 +WINE_CONFIG_DLL(dxva2,,[clean]) WINE_CONFIG_TEST(dlls/dxva2/tests) WINE_CONFIG_DLL(esent) - WINE_CONFIG_DLL(evr) + WINE_CONFIG_DLL(evr,,[clean]) diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in index d484cb14bf2..68a7e3c8c0a 100644 --- a/dlls/dxva2/Makefile.in @@ -2643,5 +2643,5 @@ index 46e431a7f29..84222dce558 100644 return E_NOINTERFACE; } -- -2.11.0 +2.14.1 diff --git a/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch b/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch index 818be333..451b78df 100644 --- a/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch +++ b/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch @@ -1,39 +1,55 @@ -From 62e317a96953781723231782f4d5b2392b347fe5 Mon Sep 17 00:00:00 2001 +From 4c3ec3a9f0ed4523f6d6f7bcba9540803eea8a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 1 Jun 2017 06:04:53 +0200 Subject: ntdll: Fix holes in ELF mappings. (v2) Based on a patch by Andrew Wesie. --- - dlls/ntdll/virtual.c | 14 ++++++++++++++ + dlls/ntdll/virtual.c | 23 +++++++++++++++++++++++ dlls/psapi/tests/psapi_main.c | 14 +++++++++++++- - 2 files changed, 27 insertions(+), 1 deletion(-) + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 25946c22c97..2305bfb47f3 100644 +index 0b813d3b0e9..b10c36c3f69 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c -@@ -1720,6 +1720,20 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) - if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_READ) ret = STATUS_SUCCESS; - else update_shared_data = FALSE; - } -+ else if (!err && (view->protect & VPROT_SYSTEM) && (VIRTUAL_GetUnixProt( vprot ) & PROT_READ)) -+ { -+ int unix_prot = VIRTUAL_GetUnixProt( vprot ); -+ unsigned char vec; +@@ -425,6 +425,16 @@ static inline BOOL is_write_watch_range( const void *addr, size_t size ) + } + + ++/*********************************************************************** ++ * is_system_range ++ */ ++static inline BOOL is_system_range( const void *addr, size_t size ) ++{ ++ struct file_view *view = VIRTUAL_FindView( addr, size ); ++ return view && (view->protect & VPROT_SYSTEM); ++} + -+ if (!VIRTUAL_SetProt( view, page, page_size, vprot )) -+ set_page_vprot_bits( page, page_size, 0, VPROT_READ | VPROT_EXEC ); -+ else if (!mincore( page, page_size, &vec ) && (vec & 1)) -+ ret = STATUS_SUCCESS; -+ else if (wine_anon_mmap( page, page_size, unix_prot, MAP_FIXED ) != page) -+ set_page_vprot_bits( page, page_size, 0, VPROT_READ | VPROT_EXEC ); -+ else -+ ret = STATUS_SUCCESS; -+ } - if (!on_signal_stack && (vprot & VPROT_GUARD)) - { - set_page_vprot_bits( page, page_size, 0, VPROT_GUARD ); ++ + /*********************************************************************** + * find_view_range + * +@@ -1822,6 +1832,19 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) + if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_READ) ret = STATUS_SUCCESS; + else update_shared_data = FALSE; + } ++ else if (!err && (VIRTUAL_GetUnixProt( vprot ) & PROT_READ) && is_system_range( page, page_size )) ++ { ++ int unix_prot = VIRTUAL_GetUnixProt( vprot ); ++ unsigned char vec; ++ ++ mprotect_range( page, page_size, 0, 0 ); ++ if (!mincore( page, page_size, &vec ) && (vec & 1)) ++ ret = STATUS_SUCCESS; ++ else if (wine_anon_mmap( page, page_size, unix_prot, MAP_FIXED ) == page) ++ ret = STATUS_SUCCESS; ++ else ++ set_page_vprot_bits( page, page_size, 0, VPROT_READ | VPROT_EXEC ); ++ } + server_leave_uninterrupted_section( &csVirtual, &sigset ); + + if (update_shared_data) diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index e35a7b694cb..e7af5bc61cc 100644 --- a/dlls/psapi/tests/psapi_main.c diff --git a/patches/ntdll-User_Shared_Data/0003-ntdll-Create-thread-to-update-user_shared_data-time-.patch b/patches/ntdll-User_Shared_Data/0003-ntdll-Create-thread-to-update-user_shared_data-time-.patch index 29818a67..37a04099 100644 --- a/patches/ntdll-User_Shared_Data/0003-ntdll-Create-thread-to-update-user_shared_data-time-.patch +++ b/patches/ntdll-User_Shared_Data/0003-ntdll-Create-thread-to-update-user_shared_data-time-.patch @@ -1,4 +1,4 @@ -From 6164061c7897abc29b28b0bb3a98b0cc525be934 Mon Sep 17 00:00:00 2001 +From fcb1675d7e732d23fb36fdf2a0da3182d0216e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Fri, 5 May 2017 05:40:50 +0200 Subject: ntdll: Create thread to update user_shared_data time values when @@ -85,10 +85,10 @@ index b405bb4e158..187e5a9b57a 100644 LdrQueryImageFileExecutionOptions( &peb->ProcessParameters->ImagePathName, globalflagW, diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index dfa808bfb29..463d88c67b9 100644 +index 043c9a64188..157c58f24f4 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h -@@ -177,6 +177,9 @@ extern void VIRTUAL_SetForceExec( BOOL enable ) DECLSPEC_HIDDEN; +@@ -181,6 +181,9 @@ extern void VIRTUAL_SetForceExec( BOOL enable ) DECLSPEC_HIDDEN; extern void virtual_release_address_space(void) DECLSPEC_HIDDEN; extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN; extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN; @@ -99,7 +99,7 @@ index dfa808bfb29..463d88c67b9 100644 /* completion */ extern NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c -index 0e73430907f..97b7383e2b8 100644 +index c42d81c7f89..81c11658a49 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -43,6 +43,7 @@ @@ -121,7 +121,7 @@ index 0e73430907f..97b7383e2b8 100644 PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter = NULL; LPTHREAD_START_ROUTINE kernel32_start_process = NULL; -@@ -355,18 +358,71 @@ static ULONG_PTR get_image_addr(void) +@@ -354,18 +357,71 @@ static ULONG_PTR get_image_addr(void) */ BYTE* CDECL __wine_user_shared_data(void) { @@ -198,7 +198,7 @@ index 0e73430907f..97b7383e2b8 100644 /*********************************************************************** * thread_init * -@@ -397,7 +453,7 @@ HANDLE thread_init(void) +@@ -396,7 +452,7 @@ HANDLE thread_init(void) MESSAGE( "wine: failed to map the shared user data: %08x\n", status ); exit(1); } @@ -208,39 +208,33 @@ index 0e73430907f..97b7383e2b8 100644 /* allocate and initialize the PEB */ diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index a452c58a44d..da7206a58b1 100644 +index 2cdcca8a599..0b813d3b0e9 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c -@@ -1758,6 +1758,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) - struct file_view *view; +@@ -1784,6 +1784,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) + { NTSTATUS ret = STATUS_ACCESS_VIOLATION; - sigset_t sigset; + void *page = ROUND_ADDR( addr, page_mask ); + BOOL update_shared_data = FALSE; + sigset_t sigset; + BYTE vprot; - server_enter_uninterrupted_section( &csVirtual, &sigset ); - if ((view = VIRTUAL_FindView( addr, 0 ))) -@@ -1774,6 +1775,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) - /* ignore fault if page is writable now */ - if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ret = STATUS_SUCCESS; - } -+ else if (!err && page == user_shared_data_external) -+ { -+ if (!(vprot & VPROT_READ)) -+ { -+ set_page_vprot_bits( page, page_size, VPROT_READ | VPROT_WRITE, 0 ); -+ mprotect_range( view, page, page_size, 0, 0 ); -+ update_shared_data = TRUE; -+ } -+ /* ignore fault if page is readable now */ -+ if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_READ) ret = STATUS_SUCCESS; -+ else update_shared_data = FALSE; -+ } - if (!on_signal_stack && (vprot & VPROT_GUARD)) - { - set_page_vprot_bits( page, page_size, 0, VPROT_GUARD ); -@@ -1782,6 +1795,10 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) +@@ -1809,7 +1810,23 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) + ret = STATUS_SUCCESS; } } ++ else if (!err && page == user_shared_data_external) ++ { ++ if (!(vprot & VPROT_READ)) ++ { ++ set_page_vprot_bits( page, page_size, VPROT_READ | VPROT_WRITE, 0 ); ++ mprotect_range( page, page_size, 0, 0 ); ++ update_shared_data = TRUE; ++ } ++ /* ignore fault if page is readable now */ ++ if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_READ) ret = STATUS_SUCCESS; ++ else update_shared_data = FALSE; ++ } server_leave_uninterrupted_section( &csVirtual, &sigset ); + + if (update_shared_data) diff --git a/patches/ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch b/patches/ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch index 25e8595a..3fe17381 100644 --- a/patches/ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch +++ b/patches/ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch @@ -1,4 +1,4 @@ -From f087db7a31a96e78b9d078b3de2dec90264efe6e Mon Sep 17 00:00:00 2001 +From a370fb90c05a5077a9285c1235767cf1b1b6fa5f Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 4 Oct 2014 02:35:44 +0200 Subject: ntdll: Trigger write watches before passing userdata pointer to @@ -6,14 +6,14 @@ Subject: ntdll: Trigger write watches before passing userdata pointer to --- dlls/advapi32/tests/security.c | 1 - - dlls/ntdll/server.c | 8 ++++++++ - 2 files changed, 8 insertions(+), 1 deletion(-) + dlls/ntdll/server.c | 9 +++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 698a9aa..e825bf9 100644 +index 41219087421..5f5c59ed100 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -1499,7 +1499,6 @@ todo_wine +@@ -1494,7 +1494,6 @@ todo_wine "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); todo_wine ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); @@ -22,10 +22,14 @@ index 698a9aa..e825bf9 100644 "Access and/or AccessStatus were changed!\n"); diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c -index 356d631..de9c186 100644 +index 1e84fbf418e..f7aca1b07b0 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c -@@ -305,6 +305,14 @@ unsigned int wine_server_call( void *req_ptr ) +@@ -314,9 +314,18 @@ unsigned int server_call_unlocked( void *req_ptr ) + */ + unsigned int wine_server_call( void *req_ptr ) + { ++ struct __server_request_info * const req = req_ptr; sigset_t old_set; unsigned int ret; @@ -38,8 +42,8 @@ index 356d631..de9c186 100644 + } + pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set ); - ret = send_request( req ); - if (!ret) ret = wait_reply( req ); + ret = server_call_unlocked( req_ptr ); + pthread_sigmask( SIG_SETMASK, &old_set, NULL ); -- -2.7.1 +2.14.1 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 831f7d02..4e1a373b 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,18 +1,18 @@ -From c43f021985b9bd0d2ac1ba0e8145b8eddb665506 Mon Sep 17 00:00:00 2001 +From edfa0038f4b084b05f2bb61ad741385c9ced2bd0 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: Properly handle PAGE_WRITECOPY protection. (try 5) For now, only enable it when a special environment variable is set. --- - dlls/ntdll/virtual.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 44 insertions(+), 7 deletions(-) + dlls/ntdll/virtual.c | 46 +++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index cb3b9aad385..7365c3ad487 100644 +index 0b813d3b0e9..977b4c1811f 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c -@@ -264,6 +264,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot ) +@@ -293,6 +293,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot ) return buffer; } @@ -34,7 +34,7 @@ index cb3b9aad385..7365c3ad487 100644 /*********************************************************************** * VIRTUAL_GetUnixProt -@@ -277,8 +292,19 @@ static int VIRTUAL_GetUnixProt( BYTE vprot ) +@@ -306,8 +321,19 @@ static int VIRTUAL_GetUnixProt( BYTE vprot ) { if (vprot & VPROT_READ) prot |= PROT_READ; if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ; @@ -55,57 +55,51 @@ index cb3b9aad385..7365c3ad487 100644 if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE; } if (!prot) prot = PROT_NONE; -@@ -1721,13 +1747,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) +@@ -932,7 +958,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size + { + TRACE( "updating watch %p-%p-%p\n", base, (char *)base + accessed_size, (char *)base + size ); + /* clear write watch flag on accessed pages */ +- set_page_vprot_bits( base, accessed_size, 0, VPROT_WRITEWATCH ); ++ set_page_vprot_bits( base, accessed_size, VPROT_WRITE, VPROT_WRITEWATCH | VPROT_WRITECOPY ); + /* restore page protections on the entire range */ + mprotect_range( base, size, 0, 0 ); + } +@@ -1803,12 +1829,13 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) + set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH ); + mprotect_range( page, page_size, 0, 0 ); + } +- /* ignore fault if page is writable now */ +- if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ++ if (vprot & VPROT_WRITECOPY) + { +- if ((vprot & VPROT_WRITEWATCH) || is_write_watch_range( page, page_size )) +- ret = STATUS_SUCCESS; ++ set_page_vprot_bits( page, page_size, VPROT_WRITE, VPROT_WRITECOPY ); ++ mprotect_range( page, page_size, 0, 0 ); + } ++ /* ignore fault if page is writable now */ ++ if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ret = STATUS_SUCCESS; + } + else if (!err && page == user_shared_data_external) { - void *page = ROUND_ADDR( addr, page_mask ); - BYTE vprot = get_page_vprot( page ); -- if ((err & EXCEPTION_WRITE_FAULT) && (view->protect & VPROT_WRITEWATCH)) -+ if (err & EXCEPTION_WRITE_FAULT) - { -- if (vprot & VPROT_WRITEWATCH) -+ if ((view->protect & VPROT_WRITEWATCH) && (vprot & VPROT_WRITEWATCH)) - { - set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH ); - mprotect_range( view, page, page_size, 0, 0 ); - } -+ if (vprot & VPROT_WRITECOPY) -+ { -+ set_page_vprot_bits( page, page_size, VPROT_WRITE, VPROT_WRITECOPY ); -+ mprotect_range( view, page, page_size, 0, 0 ); -+ } - /* ignore fault if page is writable now */ - if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ret = STATUS_SUCCESS; - } -@@ -1918,6 +1949,7 @@ NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, - struct file_view *view; - sigset_t sigset; - NTSTATUS ret = STATUS_ACCESS_VIOLATION; -+ BOOL writecopy = FALSE; +@@ -1846,11 +1873,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat + { + BYTE vprot = get_page_vprot( addr + i ); + if (vprot & VPROT_WRITEWATCH) *has_write_watch = TRUE; ++ if (vprot & VPROT_WRITECOPY) ++ { ++ vprot = (vprot & ~VPROT_WRITECOPY) | VPROT_WRITE; ++ *has_write_watch = TRUE; ++ } + if (!(VIRTUAL_GetUnixProt( vprot & ~VPROT_WRITEWATCH ) & PROT_WRITE)) + return STATUS_INVALID_USER_BUFFER; + } + if (*has_write_watch) +- mprotect_range( addr, size, 0, VPROT_WRITEWATCH ); /* temporarily enable write access */ ++ mprotect_range( addr, size, VPROT_WRITE, VPROT_WRITEWATCH | VPROT_WRITECOPY ); /* temporarily enable write access */ + return STATUS_SUCCESS; + } - if (!size) return STATUS_SUCCESS; - -@@ -1929,12 +1961,17 @@ NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, - - for (i = 0; i < total; i += page_size) - { -- int prot = VIRTUAL_GetUnixProt( get_page_vprot( page + i ) & ~VPROT_WRITEWATCH ); -- if (!(prot & PROT_WRITE)) goto done; -+ BYTE vprot = get_page_vprot( page + i ) & ~VPROT_WRITEWATCH; -+ if (vprot & VPROT_WRITECOPY) -+ { -+ vprot = (vprot & ~VPROT_WRITECOPY) | VPROT_WRITE; -+ writecopy = TRUE; -+ } -+ if (!(VIRTUAL_GetUnixProt( vprot ) & PROT_WRITE)) goto done; - } -- if (view->protect & VPROT_WRITEWATCH) /* enable write access by clearing write watches */ -+ if ((view->protect & VPROT_WRITEWATCH) || writecopy) /* enable write access by clearing write watches */ - { -- set_page_vprot_bits( addr, size, 0, VPROT_WRITEWATCH ); -+ set_page_vprot_bits( addr, size, VPROT_WRITE, VPROT_WRITECOPY | VPROT_WRITEWATCH ); - mprotect_range( view, addr, size, 0, 0 ); - } - if (buffer) memcpy( addr, buffer, size ); -- 2.14.1 diff --git a/patches/ntdll-WRITECOPY/definition b/patches/ntdll-WRITECOPY/definition index 7f107832..eca1cc4d 100644 --- a/patches/ntdll-WRITECOPY/definition +++ b/patches/ntdll-WRITECOPY/definition @@ -1,6 +1,6 @@ Fixes: [29384] Voobly expects correct handling of WRITECOPY memory protection FIxes: [35561] MSYS2 expects correct handling of WRITECOPY memory protection -Depends: ws2_32-WriteWatches +Depends: ntdll-User_Shared_Data # Causes regressions? # https://bugs.wine-staging.com/show_bug.cgi?id=207 diff --git a/patches/ntdll-WriteWatches/0001-ntdll-Avoid-race-conditions-with-write-watches-in-Nt.patch b/patches/ntdll-WriteWatches/0001-ntdll-Avoid-race-conditions-with-write-watches-in-Nt.patch deleted file mode 100644 index 67811400..00000000 --- a/patches/ntdll-WriteWatches/0001-ntdll-Avoid-race-conditions-with-write-watches-in-Nt.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 6a0ddd70ba0d958f5e0191c4ae5b74f3507a7aaf Mon Sep 17 00:00:00 2001 -From: Dmitry Timoshkov -Date: Tue, 10 Feb 2015 06:36:52 +0100 -Subject: ntdll: Avoid race-conditions with write watches in NtReadFile. - -Rebased against kernel32-NamedPipe patchset by Sebastian Lackner . ---- - dlls/kernel32/tests/virtual.c | 16 ++-------------- - dlls/ntdll/file.c | 18 ++++++++++++++++++ - 2 files changed, 20 insertions(+), 14 deletions(-) - -diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c -index 1d611cdacff..2ecd5611924 100644 ---- a/dlls/kernel32/tests/virtual.c -+++ b/dlls/kernel32/tests/virtual.c -@@ -1840,13 +1840,10 @@ static DWORD CALLBACK read_pipe( void *arg ) - "%u: ConnectNamedPipe failed %u\n", args->index, GetLastError() ); - - success = ReadFile( args->pipe, args->base, args->size, &num_bytes, NULL ); -- todo_wine -- { - ok( success, "%u: ReadFile failed %u\n", args->index, GetLastError() ); - ok( num_bytes == sizeof(testdata), "%u: wrong number of bytes read %u\n", args->index, num_bytes ); - ok( !memcmp( args->base, testdata, sizeof(testdata)), - "%u: didn't receive expected data\n", args->index ); -- } - return 0; - } - -@@ -2056,22 +2053,16 @@ static void test_write_watch(void) - - num_bytes = 0; - success = GetOverlappedResult( readpipe, &overlapped, &num_bytes, TRUE ); -- todo_wine -- { - ok( success, "%u: GetOverlappedResult failed %u\n", i, GetLastError() ); - ok( num_bytes == sizeof(testdata), "%u: wrong number of bytes read %u\n", i, num_bytes ); - ok( !memcmp( base, testdata, sizeof(testdata)), "%u: didn't receive expected data\n", i ); -- } - - count = 64; - memset( results, 0, sizeof(results) ); - ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize ); - ok( !ret, "%u: GetWriteWatch failed %u\n", i, GetLastError() ); -- todo_wine -- { -- ok( count == 1, "%u: wrong count %lu\n", i, count ); -+ todo_wine ok( count == 1, "%u: wrong count %lu\n", i, count ); - ok( results[0] == base, "%u: wrong result %p\n", i, results[0] ); -- } - - CloseHandle( readpipe ); - CloseHandle( writepipe ); -@@ -2121,11 +2112,8 @@ static void test_write_watch(void) - memset( results, 0, sizeof(results) ); - ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize ); - ok( !ret, "%u: GetWriteWatch failed %u\n", i, GetLastError() ); -- todo_wine -- { -- ok( count == 1, "%u: wrong count %lu\n", i, count ); -+ todo_wine ok( count == 1, "%u: wrong count %lu\n", i, count ); - ok( results[0] == base, "%u: wrong result %p\n", i, results[0] ); -- } - - CloseHandle( readpipe ); - CloseHandle( writepipe ); -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 0381e558ff6..a4da492573c 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -524,6 +524,10 @@ static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb, NTSTAT - { - if (errno == EAGAIN || errno == EINTR) - status = STATUS_PENDING; -+ else if (errno == EFAULT) -+ status = (wine_uninterrupted_write_memory( &fileio->buffer[fileio->already], NULL, -+ fileio->count - fileio->already ) == STATUS_SUCCESS) ? -+ STATUS_PENDING : STATUS_ACCESS_VIOLATION; - else /* check to see if the transfer is complete */ - status = FILE_GetNtStatus(); - } -@@ -871,6 +875,13 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, - /* async I/O doesn't make sense on regular files */ - while ((result = pread( unix_handle, buffer, length, offset->QuadPart )) == -1) - { -+ if (errno == EFAULT) -+ { -+ if (virtual_check_buffer_for_write( buffer, length ) >= length) -+ continue; -+ else -+ errno = EFAULT; -+ } - if (errno != EINTR) - { - status = FILE_GetNtStatus(); -@@ -945,6 +956,13 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, - else if (errno != EAGAIN) - { - if (errno == EINTR) continue; -+ if (errno == EFAULT) -+ { -+ if (wine_uninterrupted_write_memory( (char *)buffer + total, NULL, length - total ) == STATUS_SUCCESS) -+ continue; -+ else -+ errno = EFAULT; -+ } - if (!total) status = FILE_GetNtStatus(); - goto done; - } --- -2.14.1 - diff --git a/patches/ntdll-WriteWatches/definition b/patches/ntdll-WriteWatches/definition deleted file mode 100644 index 592f6edf..00000000 --- a/patches/ntdll-WriteWatches/definition +++ /dev/null @@ -1,3 +0,0 @@ -Fixes: Avoid race-conditions in NtReadFile() operations with write watches. -Depends: ws2_32-WriteWatches -# Depends: kernel32-Named_Pipe diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 949d2e7f..8e1cd3cb 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "25a8773d21d0113dc5e4f9dee49d9d9dbeed347b" + echo "44cb0afb2571984bda8ca1fa084a50c1fc04ac71" } # Show version information @@ -294,7 +294,6 @@ patch_enable_all () enable_ntdll_User_Shared_Data="$1" enable_ntdll_WRITECOPY="$1" enable_ntdll_Wait_User_APC="$1" - enable_ntdll_WriteWatches="$1" enable_ntdll_Zero_mod_name="$1" enable_ntdll__aulldvrm="$1" enable_ntdll_call_thread_func_wrapper="$1" @@ -1159,9 +1158,6 @@ patch_enable () ntdll-Wait_User_APC) enable_ntdll_Wait_User_APC="$2" ;; - ntdll-WriteWatches) - enable_ntdll_WriteWatches="$2" - ;; ntdll-Zero_mod_name) enable_ntdll_Zero_mod_name="$2" ;; @@ -2553,13 +2549,6 @@ if test "$enable_nvapi_Stub_DLL" -eq 1; then enable_nvcuda_CUDA_Support=1 fi -if test "$enable_ntdll_WriteWatches" -eq 1; then - if test "$enable_ws2_32_WriteWatches" -gt 1; then - abort "Patchset ws2_32-WriteWatches disabled, but ntdll-WriteWatches depends on that." - fi - enable_ws2_32_WriteWatches=1 -fi - if test "$enable_ntdll_SystemRoot_Symlink" -eq 1; then if test "$enable_ntdll_Exception" -gt 1; then abort "Patchset ntdll-Exception disabled, but ntdll-SystemRoot_Symlink depends on that." @@ -2575,10 +2564,10 @@ if test "$enable_ntdll_Signal_Handler" -eq 1; then fi if test "$enable_ntdll_WRITECOPY" -eq 1; then - if test "$enable_ws2_32_WriteWatches" -gt 1; then - abort "Patchset ws2_32-WriteWatches disabled, but ntdll-WRITECOPY depends on that." + if test "$enable_ntdll_User_Shared_Data" -gt 1; then + abort "Patchset ntdll-User_Shared_Data disabled, but ntdll-WRITECOPY depends on that." fi - enable_ws2_32_WriteWatches=1 + enable_ntdll_User_Shared_Data=1 fi if test "$enable_ntdll_RtlIpStringToAddress_Tests" -eq 1; then @@ -2961,9 +2950,10 @@ fi # | Modified files: # | * dlls/amstream/mediastreamfilter.c, dlls/d2d1/brush.c, dlls/d2d1/geometry.c, dlls/d3d11/view.c, dlls/d3d8/texture.c, # | dlls/d3d9/tests/visual.c, dlls/d3d9/texture.c, dlls/ddraw/viewport.c, dlls/dsound/primary.c, dlls/dwrite/font.c, -# | dlls/dwrite/layout.c, dlls/msxml3/schema.c, dlls/netapi32/netapi32.c, dlls/ole32/storage32.h, dlls/oleaut32/oleaut.c, -# | dlls/rpcrt4/cstub.c, dlls/vbscript/vbdisp.c, dlls/wined3d/glsl_shader.c, dlls/ws2_32/tests/sock.c, -# | dlls/wsdapi/msgparams.c, include/wine/list.h, include/wine/rbtree.h, include/winnt.h, tools/makedep.c +# | dlls/dwrite/layout.c, dlls/evr/evr.c, dlls/msxml3/schema.c, dlls/netapi32/netapi32.c, dlls/ole32/storage32.h, +# | dlls/oleaut32/oleaut.c, dlls/rpcrt4/cstub.c, dlls/vbscript/vbdisp.c, dlls/wined3d/glsl_shader.c, +# | dlls/ws2_32/tests/sock.c, dlls/wsdapi/msgparams.c, include/wine/list.h, include/wine/rbtree.h, include/winnt.h, +# | tools/makedep.c # | if test "$enable_Compiler_Warnings" -eq 1; then patch_apply Compiler_Warnings/0001-ole32-Fix-compilation-with-recent-versions-of-gcc.patch @@ -2983,6 +2973,7 @@ if test "$enable_Compiler_Warnings" -eq 1; then patch_apply Compiler_Warnings/0030-vbscript-Avoid-implicit-cast-of-interface-pointer.patch patch_apply Compiler_Warnings/0031-include-Check-element-type-in-CONTAINING_RECORD-and-.patch patch_apply Compiler_Warnings/0032-wsdapi-Avoid-implicit-cast-of-interface-pointer.patch + patch_apply Compiler_Warnings/0033-evr-Avoid-implicit-cast-of-interface-pointer.patch ( printf '%s\n' '+ { "Sebastian Lackner", "ole32: Fix compilation with recent versions of gcc.", 1 },'; printf '%s\n' '+ { "Sebastian Lackner", "ws2_32/tests: Work around an incorrect detection in GCC 7.", 1 },'; @@ -3001,6 +2992,7 @@ if test "$enable_Compiler_Warnings" -eq 1; then printf '%s\n' '+ { "Sebastian Lackner", "vbscript: Avoid implicit cast of interface pointer.", 1 },'; printf '%s\n' '+ { "Sebastian Lackner", "include: Check element type in CONTAINING_RECORD and similar macros.", 1 },'; printf '%s\n' '+ { "Sebastian Lackner", "wsdapi: Avoid implicit cast of interface pointer.", 1 },'; + printf '%s\n' '+ { "Sebastian Lackner", "evr: Avoid implicit cast of interface pointer.", 1 },'; ) >> "$patchlist" fi @@ -6809,25 +6801,11 @@ if test "$enable_ntdll_Serial_Port_Detection" -eq 1; then ) >> "$patchlist" fi -# Patchset ws2_32-WriteWatches -# | -# | Modified files: -# | * dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_i386.c, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c, -# | dlls/ws2_32/tests/sock.c, include/winternl.h -# | -if test "$enable_ws2_32_WriteWatches" -eq 1; then - patch_apply ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch - patch_apply ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch - ( - printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Expose wine_uninterrupted_[read|write]_memory as exports.", 1 },'; - printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-WRITECOPY # | # | This patchset has the following (direct or indirect) dependencies: -# | * ws2_32-WriteWatches +# | * ntdll-Attach_Process_DLLs, ntdll-ThreadTime, ntdll-Hide_Wine_Exports, ntdll-x86_64_ExceptionInformation, ntdll- +# | User_Shared_Data # | # | This patchset fixes the following Wine bugs: # | * [#29384] Voobly expects correct handling of WRITECOPY memory protection @@ -6854,7 +6832,8 @@ fi # Patchset ntdll-Signal_Handler # | # | This patchset has the following (direct or indirect) dependencies: -# | * ws2_32-WriteWatches, ntdll-WRITECOPY +# | * ntdll-Attach_Process_DLLs, ntdll-ThreadTime, ntdll-Hide_Wine_Exports, ntdll-x86_64_ExceptionInformation, ntdll- +# | User_Shared_Data, ntdll-WRITECOPY # | # | Modified files: # | * dlls/ntdll/signal_i386.c @@ -6971,21 +6950,6 @@ if test "$enable_ntdll_Wait_User_APC" -eq 1; then ) >> "$patchlist" fi -# Patchset ntdll-WriteWatches -# | -# | This patchset has the following (direct or indirect) dependencies: -# | * ws2_32-WriteWatches -# | -# | Modified files: -# | * dlls/kernel32/tests/virtual.c, dlls/ntdll/file.c -# | -if test "$enable_ntdll_WriteWatches" -eq 1; then - patch_apply ntdll-WriteWatches/0001-ntdll-Avoid-race-conditions-with-write-watches-in-Nt.patch - ( - printf '%s\n' '+ { "Dmitry Timoshkov", "ntdll: Avoid race-conditions with write watches in NtReadFile.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-Zero_mod_name # | # | Modified files: @@ -10565,6 +10529,18 @@ if test "$enable_ws2_32_WSACleanup" -eq 1; then ) >> "$patchlist" fi +# Patchset ws2_32-WriteWatches +# | +# | Modified files: +# | * dlls/ntdll/ntdll.spec, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c +# | +if test "$enable_ws2_32_WriteWatches" -eq 1; then + patch_apply ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch + ( + printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },'; + ) >> "$patchlist" +fi + # Patchset ws2_32-getaddrinfo # | # | Modified files: diff --git a/patches/ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch b/patches/ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch deleted file mode 100644 index 8e4cd610..00000000 --- a/patches/ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 6d426bf5815052c59127d85383a82e080a00f21b Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 3 Jan 2015 20:07:08 +0100 -Subject: ntdll: Expose wine_uninterrupted_[read|write]_memory as exports. - ---- - dlls/ntdll/ntdll.spec | 4 ++++ - dlls/ntdll/ntdll_misc.h | 2 -- - dlls/ntdll/signal_i386.c | 12 ++++++------ - dlls/ntdll/virtual.c | 26 ++++++++++++++++---------- - include/winternl.h | 3 +++ - 5 files changed, 29 insertions(+), 18 deletions(-) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 69bfe923234..5d5fa5b5c4e 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -1495,6 +1495,10 @@ - # signal handling - @ cdecl __wine_set_signal_handler(long ptr) - -+# Virtual memory management -+@ cdecl wine_uninterrupted_read_memory(ptr ptr long) -+@ cdecl wine_uninterrupted_write_memory(ptr ptr long) -+ - # Filesystem - @ cdecl wine_nt_to_unix_file_name(ptr ptr long long) - @ cdecl wine_unix_to_nt_file_name(ptr ptr) -diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index 3358119657d..af142a31c70 100644 ---- a/dlls/ntdll/ntdll_misc.h -+++ b/dlls/ntdll/ntdll_misc.h -@@ -173,8 +173,6 @@ extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLS - extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) DECLSPEC_HIDDEN; - extern BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size ) DECLSPEC_HIDDEN; - extern BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size ) DECLSPEC_HIDDEN; --extern SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ) DECLSPEC_HIDDEN; --extern NTSTATUS virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size ) DECLSPEC_HIDDEN; - extern void VIRTUAL_SetForceExec( BOOL enable ) DECLSPEC_HIDDEN; - extern void virtual_release_address_space(void) DECLSPEC_HIDDEN; - extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN; -diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c -index ab8d1144472..94b06214568 100644 ---- a/dlls/ntdll/signal_i386.c -+++ b/dlls/ntdll/signal_i386.c -@@ -1802,14 +1802,14 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context ) - union atl_thunk thunk_copy; - SIZE_T thunk_len; - -- thunk_len = virtual_uninterrupted_read_memory( thunk, &thunk_copy, sizeof(*thunk) ); -+ thunk_len = wine_uninterrupted_read_memory( thunk, &thunk_copy, sizeof(*thunk) ); - if (!thunk_len) return FALSE; - - if (thunk_len >= sizeof(thunk_copy.t1) && thunk_copy.t1.movl == 0x042444c7 && - thunk_copy.t1.jmp == 0xe9) - { -- if (!virtual_uninterrupted_write_memory( (DWORD *)context->Esp + 1, -- &thunk_copy.t1.this, sizeof(DWORD) )) -+ if (!wine_uninterrupted_write_memory( (DWORD *)context->Esp + 1, -+ &thunk_copy.t1.this, sizeof(DWORD) )) - { - context->Eip = (DWORD_PTR)(&thunk->t1.func + 1) + thunk_copy.t1.func; - TRACE( "emulating ATL thunk type 1 at %p, func=%08x arg=%08x\n", -@@ -1852,11 +1852,11 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context ) - thunk_copy.t5.inst2 == 0x0460) - { - DWORD func, stack[2]; -- if (virtual_uninterrupted_read_memory( (DWORD *)context->Esp, -+ if (wine_uninterrupted_read_memory( (DWORD *)context->Esp, - stack, sizeof(stack) ) == sizeof(stack) && -- virtual_uninterrupted_read_memory( (DWORD *)stack[1] + 1, -+ wine_uninterrupted_read_memory( (DWORD *)stack[1] + 1, - &func, sizeof(DWORD) ) == sizeof(DWORD) && -- !virtual_uninterrupted_write_memory( (DWORD *)context->Esp + 1, &stack[0], sizeof(stack[0]) )) -+ !wine_uninterrupted_write_memory( (DWORD *)context->Esp + 1, &stack[0], sizeof(stack[0]) )) - { - context->Ecx = stack[0]; - context->Eax = stack[1]; -diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index a73041706f7..cb3b9aad385 100644 ---- a/dlls/ntdll/virtual.c -+++ b/dlls/ntdll/virtual.c -@@ -1862,13 +1862,14 @@ BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size ) - - - /*********************************************************************** -- * virtual_uninterrupted_read_memory -+ * wine_uninterrupted_read_memory (NTDLL.@) - * - * Similar to NtReadVirtualMemory, but without wineserver calls. Moreover - * permissions are checked before accessing each page, to ensure that no -- * exceptions can happen. -+ * exceptions can happen. When a NULL pointer is passed as buffer the -+ * permissions are only checked and no actual memcpy is performed. - */ --SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ) -+SIZE_T CDECL wine_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ) - { - struct file_view *view; - sigset_t sigset; -@@ -1886,10 +1887,14 @@ SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T - while (bytes_read < size && (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_READ)) - { - SIZE_T block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) ); -- memcpy( buffer, addr, block_size ); - -- addr = (const void *)((const char *)addr + block_size); -- buffer = (void *)((char *)buffer + block_size); -+ if (buffer) -+ { -+ memcpy( buffer, addr, block_size ); -+ buffer = (void *)((char *)buffer + block_size); -+ } -+ -+ addr = (const void *)((const char *)addr + block_size); - bytes_read += block_size; - page += page_size; - } -@@ -1901,13 +1906,14 @@ SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T - - - /*********************************************************************** -- * virtual_uninterrupted_write_memory -+ * wine_uninterrupted_write_memory - * - * Similar to NtWriteVirtualMemory, but without wineserver calls. Moreover - * permissions are checked before accessing each page, to ensure that no -- * exceptions can happen. -+ * exceptions can happen. When a NULL pointer is passed as buffer the -+ * permissions are only checked and no actual memcpy is performed. - */ --NTSTATUS virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size ) -+NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size ) - { - struct file_view *view; - sigset_t sigset; -@@ -1931,7 +1937,7 @@ NTSTATUS virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZ - set_page_vprot_bits( addr, size, 0, VPROT_WRITEWATCH ); - mprotect_range( view, addr, size, 0, 0 ); - } -- memcpy( addr, buffer, size ); -+ if (buffer) memcpy( addr, buffer, size ); - ret = STATUS_SUCCESS; - } - done: -diff --git a/include/winternl.h b/include/winternl.h -index 3d60baa1f98..3ff6c38d6dc 100644 ---- a/include/winternl.h -+++ b/include/winternl.h -@@ -2790,6 +2790,9 @@ NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, - UINT disposition, BOOLEAN check_case ); - NTSYSAPI NTSTATUS CDECL wine_unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt ); - -+NTSYSAPI SIZE_T CDECL wine_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T size ); -+NTSYSAPI NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size ); -+ - - /*********************************************************************** - * Inline functions --- -2.14.1 - diff --git a/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch b/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch index 943d9f82..1152b524 100644 --- a/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch +++ b/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch @@ -1,4 +1,4 @@ -From 7c4a78a160ee6b8a23a1eac779901faae5cb2335 Mon Sep 17 00:00:00 2001 +From cab68a82435dfc0cd55f65dca6febae250681f14 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 21 Nov 2014 12:22:46 +0100 Subject: ws2_32: Avoid race-conditions of async WSARecv() operations with @@ -37,41 +37,116 @@ Based on the code it looks like we could savely remove the write-watch check at the beginning of WS2_recv_base, which might make the application think that data is immediately available. --- - dlls/ws2_32/socket.c | 15 ++++++++++++++- + dlls/ntdll/ntdll.spec | 3 +++ + dlls/ntdll/virtual.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/ws2_32/socket.c | 4 +++- dlls/ws2_32/tests/sock.c | 11 +++-------- - 2 files changed, 17 insertions(+), 9 deletions(-) + 4 files changed, 54 insertions(+), 9 deletions(-) +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 68d7f22b192..b4acd5e6feb 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -1491,6 +1491,9 @@ + # signal handling + @ cdecl __wine_set_signal_handler(long ptr) + ++# Virtal memory management ++@ cdecl wine_virtual_locked_recvmsg(long ptr long) ++ + # Filesystem + @ cdecl wine_nt_to_unix_file_name(ptr ptr long long) + @ cdecl wine_unix_to_nt_file_name(ptr ptr) +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index 2cdcca8a599..7e22a8a9bcf 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -41,6 +41,9 @@ + #ifdef HAVE_SYS_SYSINFO_H + # include + #endif ++#ifdef HAVE_SYS_SOCKET_H ++# include ++#endif + #ifdef HAVE_VALGRIND_VALGRIND_H + # include + #endif +@@ -1913,6 +1916,48 @@ ssize_t virtual_locked_pread( int fd, void *addr, size_t size, off_t offset ) + } + + ++/*********************************************************************** ++ * virtual_locked_recvmsg ++ */ ++ssize_t CDECL wine_virtual_locked_recvmsg( int sockfd, struct msghdr *msg, int flags ) ++{ ++ sigset_t sigset; ++ BOOL has_write_watch = FALSE; ++ int err = EFAULT; ++ int i; ++ ++ ssize_t size, ret = recvmsg( sockfd, msg, flags ); ++ if (ret != -1 || errno != EFAULT) return ret; ++ ++ server_enter_uninterrupted_section( &csVirtual, &sigset ); ++ ++ for (i = 0; i < msg->msg_iovlen; i++) ++ { ++ struct iovec *iov = &msg->msg_iov[i]; ++ if (check_write_access( iov->iov_base, iov->iov_len, &has_write_watch )) ++ { ++ while (i--) update_write_watches( msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, 0 ); ++ goto done; ++ } ++ } ++ ++ size = ret = recvmsg( sockfd, msg, flags ); ++ err = errno; ++ ++ if (!has_write_watch) goto done; ++ for (i = 0; i < msg->msg_iovlen; i++) ++ { ++ struct iovec *iov = &msg->msg_iov[i]; ++ update_write_watches( iov->iov_base, iov->iov_len, min( max( 0, size ), iov->iov_len )); ++ size -= iov->iov_len; ++ } ++ ++done: ++ server_leave_uninterrupted_section( &csVirtual, &sigset ); ++ errno = err; ++ return ret; ++} ++ + + /*********************************************************************** + * virtual_is_valid_code_address diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index 681f340bc6d..ac356035cc6 100644 +index 681f340bc6d..e97b8ebfe69 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2358,7 +2358,20 @@ static int WS2_recv( int fd, struct ws2_async *wsa, int flags ) +@@ -263,6 +263,8 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSABUF lpControlBuffer ); - while ((n = recvmsg(fd, &hdr, flags)) == -1) ++extern ssize_t CDECL wine_virtual_locked_recvmsg( int sockfd, struct msghdr *msg, int flags ); ++ + /* critical section to protect some non-reentrant net function */ + static CRITICAL_SECTION csWSgetXXXbyYYY; + static CRITICAL_SECTION_DEBUG critsect_debug = +@@ -2356,7 +2358,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa, int flags ) + hdr.msg_flags = 0; + #endif + +- while ((n = recvmsg(fd, &hdr, flags)) == -1) ++ while ((n = wine_virtual_locked_recvmsg(fd, &hdr, flags)) == -1) { -- if (errno != EINTR) -+ if (errno == EFAULT) -+ { -+ unsigned int i; -+ for (i = wsa->first_iovec; i < wsa->n_iovecs; i++) -+ { -+ struct iovec *iov = &wsa->iovec[i]; -+ if (wine_uninterrupted_write_memory( iov->iov_base, NULL, iov->iov_len ) != STATUS_SUCCESS) -+ { -+ errno = EFAULT; -+ return -1; -+ } -+ } -+ } -+ else if (errno != EINTR) + if (errno != EINTR) return -1; - } - diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 02f7473215d..e1e37404b72 100644 +index 7b0cc322dad..12b90e979f9 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6962,18 +6962,15 @@ static void test_write_watch(void) +@@ -6963,18 +6963,15 @@ static void test_write_watch(void) send(src, "test message", sizeof("test message"), 0); ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE ); @@ -91,7 +166,7 @@ index 02f7473215d..e1e37404b72 100644 memset( base, 0, size ); count = 64; -@@ -6984,7 +6981,6 @@ static void test_write_watch(void) +@@ -6985,7 +6982,6 @@ static void test_write_watch(void) bufs[1].len = 0x4000; bufs[1].buf = base + 0x2000; ret = WSARecvFrom( dest, bufs, 2, NULL, &flags, &addr, &addr_len, &ov, NULL); @@ -99,7 +174,7 @@ index 02f7473215d..e1e37404b72 100644 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", ret, GetLastError()); -@@ -6992,7 +6988,6 @@ static void test_write_watch(void) +@@ -6993,7 +6989,6 @@ static void test_write_watch(void) ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize ); ok( !ret, "GetWriteWatch failed %u\n", GetLastError() ); ok( count == 5, "wrong count %lu\n", count ); @@ -107,7 +182,7 @@ index 02f7473215d..e1e37404b72 100644 ok( !base[0], "data set\n" ); send(src, "test message", sizeof("test message"), 0); -@@ -7006,7 +7001,7 @@ static void test_write_watch(void) +@@ -7007,7 +7002,7 @@ static void test_write_watch(void) count = 64; ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize ); ok( !ret, "GetWriteWatch failed %u\n", GetLastError() ); @@ -116,7 +191,7 @@ index 02f7473215d..e1e37404b72 100644 memset( base, 0, size ); count = 64; -@@ -7035,7 +7030,7 @@ static void test_write_watch(void) +@@ -7036,7 +7031,7 @@ static void test_write_watch(void) count = 64; ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize ); ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );