Fix issue in ws2_32-WriteWatches patch which can cause exceptions on the signal stack.

This commit is contained in:
Sebastian Lackner 2015-01-03 21:16:10 +01:00
parent 90c12baba2
commit 4c95b9d483
11 changed files with 288 additions and 36 deletions

1
debian/changelog vendored
View File

@ -4,6 +4,7 @@ wine-staging (1.7.34) UNRELEASED; urgency=low
* Avoid duplicate wined3d specfile by adding PARENTSPEC Makefile argument.
* Fix issue in DOS Attributes patch which broke ./configure on systems with alternative shells.
* Fix issue in user32-WndProc patch which caused crashes for some 16-bit apps.
* Fix issue in ws2_32-WriteWatches patch which can cause exceptions on the signal stack.
* Added patch with stubs for WinSqm[Start|End]Session.
* Added patch to fix handling of subdirectory in FtpFindFirstFile.
* Added patch to return proper charcount for GetLocaleInfo with LOCALE_IFIRSTDAYOFWEEK.

View File

@ -1284,17 +1284,17 @@ ntdll-User_Shared_Data.ok:
# | dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c
# |
.INTERMEDIATE: ntdll-WRITECOPY.ok
ntdll-WRITECOPY.ok:
ntdll-WRITECOPY.ok: ws2_32-WriteWatches.ok
$(call APPLY_FILE,ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch)
$(call APPLY_FILE,ntdll-WRITECOPY/0002-advapi-Trigger-write-watches-before-passing-userdata.patch)
$(call APPLY_FILE,ntdll-WRITECOPY/0003-ntdll-Setup-a-temporary-signal-handler-during-proces.patch)
$(call APPLY_FILE,ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.patch)
$(call APPLY_FILE,ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch)
$(call APPLY_FILE,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.", 1 },'; \
echo '+ { "Michael Müller", "ntdll: Properly handle PAGE_WRITECOPY protection.", 4 },'; \
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 },'; \
) > ntdll-WRITECOPY.ok
@ -2701,13 +2701,18 @@ ws2_32-TransmitFile.ok:
# Patchset ws2_32-WriteWatches
# |
# | Modified files:
# | * dlls/ws2_32/socket.c
# | * dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_i386.c, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c,
# | include/winternl.h
# |
.INTERMEDIATE: ws2_32-WriteWatches.ok
ws2_32-WriteWatches.ok:
$(call APPLY_FILE,ws2_32-WriteWatches/0001-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch)
$(call APPLY_FILE,ws2_32-WriteWatches/0001-ntdll-Handle-write-watches-in-virtual_uninterrupted_.patch)
$(call APPLY_FILE,ws2_32-WriteWatches/0002-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch)
$(call APPLY_FILE,ws2_32-WriteWatches/0003-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch)
@( \
echo '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 1 },'; \
echo '+ { "Sebastian Lackner", "ntdll: Handle write watches in virtual_uninterrupted_write_memory.", 1 },'; \
echo '+ { "Sebastian Lackner", "ntdll: Expose wine_uninterrupted_[read|write]_memory as exports.", 1 },'; \
echo '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },'; \
) > ws2_32-WriteWatches.ok
# Patchset ws2_32-getaddrinfo

View File

@ -1,4 +1,4 @@
From 482071f086b4e93d8bd9e1c57652478bfcd98ecf Mon Sep 17 00:00:00 2001
From e4f9424f025aebdbcd96a6f0eb2c39f479b4eda7 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 4 Oct 2014 02:35:44 +0200
Subject: ntdll: Trigger write watches before passing userdata pointer to
@ -28,5 +28,5 @@ index aabda4f..4d5d4ba 100644
ret = send_request( req );
if (!ret) ret = wait_reply( req );
--
2.1.1
2.2.1

View File

@ -1,4 +1,4 @@
From 1eeeb531c7e0188ecf7f39166dfe299fef2c7116 Mon Sep 17 00:00:00 2001
From adcf73538130589e5c4831ec5a8fdd37a6408824 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 4 Oct 2014 02:38:27 +0200
Subject: advapi: Trigger write watches before passing userdata pointer to read
@ -23,5 +23,5 @@ index b2be5e3..50502b8 100644
close(dev_random);
return TRUE;
--
2.1.1
2.2.1

View File

@ -1,4 +1,4 @@
From cbb34fc193e2b2236ef7fec301e6d34be39d92aa Mon Sep 17 00:00:00 2001
From 91cdcf5f955d3cbd7a22531054448dc01c171e66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 02:53:22 +0200
Subject: ntdll: Setup a temporary signal handler during process startup to
@ -15,7 +15,7 @@ Subject: ntdll: Setup a temporary signal handler during process startup to
7 files changed, 73 insertions(+)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4370084..53e6b55 100644
index e56e78b..a33f7a0 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -67,6 +67,7 @@ extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
@ -61,10 +61,10 @@ index 8c8f7af..483bc85 100644
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 12aa5a4..d24e3bf 100644
index de55c31..49222f4 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1949,6 +1949,30 @@ static void usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
@@ -2035,6 +2035,30 @@ static void usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
/**********************************************************************
@ -95,7 +95,7 @@ index 12aa5a4..d24e3bf 100644
* segv_handler
*
* Handler for SIGSEGV and related errors.
@@ -2371,6 +2395,29 @@ void signal_init_process(void)
@@ -2457,6 +2481,29 @@ void signal_init_process(void)
exit(1);
}
@ -172,5 +172,5 @@ index c8461b0..a2937c2 100644
/* reserve space for shared user data */
--
2.1.1
2.2.1

View File

@ -1,18 +1,18 @@
From 0596c2b03fa72a5159fa5a9df3e909e925d6144f Mon Sep 17 00:00:00 2001
From 9e5ef34f4cbfb381528750caabd4ba6a3da439f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 02:56:08 +0200
Subject: ntdll: Properly handle PAGE_WRITECOPY protection. (try 4)
Subject: ntdll: Properly handle PAGE_WRITECOPY protection. (try 5)
---
dlls/kernel32/tests/virtual.c | 12 ++----------
dlls/ntdll/virtual.c | 16 +++++++++++++---
2 files changed, 15 insertions(+), 13 deletions(-)
dlls/ntdll/virtual.c | 26 +++++++++++++++++++-------
2 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 73b753e..5797805 100644
index 75e91d5..3520546 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -2786,11 +2786,7 @@ todo_wine
@@ -2929,11 +2929,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = VirtualQuery(base, &info, sizeof(info));
ok(ret, "VirtualQuery failed %d\n", GetLastError());
@ -25,7 +25,7 @@ index 73b753e..5797805 100644
}
}
else
@@ -2804,11 +2800,7 @@ todo_wine
@@ -2947,11 +2943,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot);
ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
@ -39,7 +39,7 @@ index 73b753e..5797805 100644
UnmapViewOfFile(base);
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 4c4c05d..d26fe26 100644
index 17792e1..36d8836 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -179,8 +179,13 @@ static int VIRTUAL_GetUnixProt( BYTE vprot )
@ -78,6 +78,27 @@ index 4c4c05d..d26fe26 100644
/* ignore fault if page is writable now */
if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
}
@@ -1748,14 +1758,16 @@ SIZE_T CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SI
* handle guard pages here. */
if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
{
- if (!(view->protect & VPROT_WRITEWATCH))
- break;
-
- if (*p & VPROT_WRITEWATCH)
+ if ((view->protect & VPROT_WRITEWATCH) && (*p & VPROT_WRITEWATCH))
{
*p &= ~VPROT_WRITEWATCH;
VIRTUAL_SetProt( view, page, page_size, *p );
}
+ if (*p & VPROT_WRITECOPY)
+ {
+ *p = (*p & ~VPROT_WRITECOPY) | VPROT_WRITE;
+ VIRTUAL_SetProt( view, page, page_size, *p );
+ }
/* ignore fault if page is writable now */
if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
break;
--
2.1.2
2.2.1

View File

@ -1,4 +1,4 @@
From 566ff0e978e59354160a1d2cdde79cb9e5ead244 Mon Sep 17 00:00:00 2001
From 3d29cd7c6feabae6c5ae5941f49c663b1fb78ab8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 03:22:09 +0200
Subject: ntdll: Only enable true WRITECOPY protection when a special
@ -9,7 +9,7 @@ Subject: ntdll: Only enable true WRITECOPY protection when a special
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index d26fe26..02e32fb 100644
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 )
@ -50,5 +50,5 @@ index d26fe26..02e32fb 100644
/* FIXME: Architecture needs implementation of signal_init_early. */
if (vprot & VPROT_WRITECOPY) prot |= PROT_WRITE | PROT_READ;
--
2.1.2
2.2.1

View File

@ -1 +1,2 @@
Fixes: [29384] Voobly expects correct handling of WRITECOPY memory protection
Depends: ws2_32-WriteWatches

View File

@ -0,0 +1,54 @@
From 67e51503f973289b85c526eb05d76d78f7bd337e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 3 Jan 2015 19:11:40 +0100
Subject: ntdll: Handle write watches in virtual_uninterrupted_write_memory.
---
dlls/ntdll/virtual.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 4c4c05d..8823164 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1730,12 +1730,32 @@ SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_
{
if (!(view->protect & VPROT_SYSTEM))
{
- void *page = ROUND_ADDR( addr, page_mask );
- BYTE *p = view->prot + (((const char *)page - (const char *)view->base) >> page_shift);
-
- while (bytes_written < size && (VIRTUAL_GetUnixProt( *p++ ) & PROT_WRITE))
+ while (bytes_written < size)
{
- SIZE_T block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) );
+ void *page = ROUND_ADDR( addr, page_mask );
+ BYTE *p = view->prot + (((const char *)page - (const char *)view->base) >> page_shift);
+ SIZE_T block_size;
+
+ /* If the page is not writeable then check for write watches
+ * before giving up. This can be done without raising a real
+ * exception. Similar to virtual_handle_fault, but we can't
+ * handle guard pages here. */
+ if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
+ {
+ if (!(view->protect & VPROT_WRITEWATCH))
+ break;
+
+ if (*p & VPROT_WRITEWATCH)
+ {
+ *p &= ~VPROT_WRITEWATCH;
+ VIRTUAL_SetProt( view, page, page_size, *p );
+ }
+ /* ignore fault if page is writable now */
+ if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
+ break;
+ }
+
+ block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) );
memcpy( addr, buffer, block_size );
addr = (void *)((char *)addr + block_size);
--
2.2.1

View File

@ -0,0 +1,169 @@
From 32e36972905ea820ac557c37b6d3a02dd32fd795 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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 | 10 +++++-----
dlls/ntdll/virtual.c | 34 ++++++++++++++++++++++------------
include/winternl.h | 3 +++
5 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 51de6e7..1e91089 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1430,6 +1430,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 b7ea6dc..e56e78b 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -171,8 +171,6 @@ extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLS
extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err ) 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 SIZE_T 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 1a69bc0..de55c31 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1669,13 +1669,13 @@ 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,
+ if (wine_uninterrupted_write_memory( (DWORD *)context->Esp + 1,
&thunk_copy.t1.this, sizeof(DWORD) ) == sizeof(DWORD))
{
context->Eip = (DWORD_PTR)(&thunk->t1.func + 1) + thunk_copy.t1.func;
@@ -1719,11 +1719,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,
+ wine_uninterrupted_write_memory( (DWORD *)context->Esp + 1,
&stack[0], sizeof(stack[0]) ) == sizeof(stack[0]))
{
context->Ecx = stack[0];
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 8823164..17792e1 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1672,13 +1672,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;
@@ -1697,10 +1698,14 @@ SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T
while (bytes_read < size && (VIRTUAL_GetUnixProt( *p++ ) & 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;
}
}
@@ -1711,13 +1716,14 @@ SIZE_T virtual_uninterrupted_read_memory( const void *addr, void *buffer, SIZE_T
/***********************************************************************
- * virtual_uninterrupted_write_memory
+ * wine_uninterrupted_write_memory (NTDLL.@)
*
* 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.
*/
-SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size )
+SIZE_T CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size )
{
struct file_view *view;
sigset_t sigset;
@@ -1756,10 +1762,14 @@ SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_
}
block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) );
- memcpy( addr, buffer, block_size );
- addr = (void *)((char *)addr + block_size);
- buffer = (const void *)((const char *)buffer + block_size);
+ if (buffer)
+ {
+ memcpy( addr, buffer, block_size );
+ buffer = (const void *)((const char *)buffer + block_size);
+ }
+
+ addr = (void *)((char *)addr + block_size);
bytes_written += block_size;
}
}
diff --git a/include/winternl.h b/include/winternl.h
index 1a694da..02dda9a 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2605,6 +2605,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 SIZE_T CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_T size );
+
/***********************************************************************
* Inline functions
--
2.2.1

View File

@ -1,8 +1,8 @@
From dc07ceb5dff69b2a306278d5d3254c18c98205df Mon Sep 17 00:00:00 2001
From ae757e6bb862919e3b5a59bdb590555c462258ee Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 21 Nov 2014 12:22:46 +0100
Subject: ws2_32: Avoid race-conditions of async WSARecv() operations with
write watches.
write watches. (try 2)
Under specific circumstances Silverlight resets the write watch while the async
WSARecv() operation is still pending:
@ -37,14 +37,14 @@ 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 | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
dlls/ws2_32/socket.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index b3db306..ef86b28 100644
index a9ab0a5..9d94893 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1930,7 +1930,16 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
@@ -1930,7 +1930,17 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
while ((n = recvmsg(fd, &hdr, wsa->flags)) == -1)
{
@ -54,7 +54,8 @@ index b3db306..ef86b28 100644
+ unsigned int i;
+ for (i = wsa->first_iovec; i < wsa->n_iovecs; i++)
+ {
+ if (IsBadWritePtr( wsa->iovec[i].iov_base, wsa->iovec[i].iov_len ))
+ struct iovec *iov = &wsa->iovec[i];
+ if (wine_uninterrupted_write_memory( iov->iov_base, NULL, iov->iov_len ) < iov->iov_len)
+ return -1;
+ }
+ }
@ -63,5 +64,5 @@ index b3db306..ef86b28 100644
}
--
2.1.3
2.2.1