Added patch to avoid race-conditions with write watches in WS2_async_accept.

This commit is contained in:
Sebastian Lackner
2015-02-10 07:37:49 +01:00
parent e8d4cc0cb0
commit 1ffd40e9de
6 changed files with 83 additions and 4 deletions

View File

@@ -0,0 +1,76 @@
From 373361ca2f09176e7c587879703ba176dc1ccb38 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 10 Feb 2015 07:31:21 +0100
Subject: ws2_32: Avoid race-condition with write watches in WS2_async_accept.
---
dlls/ws2_32/socket.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 8b34e5b..72bffa5 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -363,4 +363,5 @@ typedef struct ws2_accept_async
int remote_len;
struct ws2_async *read;
+ char name_buf[1];
} ws2_accept_async;
@@ -2065,7 +2066,6 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta
{
struct ws2_accept_async *wsa = arg;
int len;
- char *addr;
TRACE("status: 0x%x listen: %p, accept: %p\n", status, wsa->listen_socket, wsa->accept_socket);
@@ -2095,17 +2095,29 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta
goto finish;
/* WS2 Spec says size param is extra 16 bytes long...what do we put in it? */
- addr = ((char *)wsa->buf) + wsa->data_len;
len = wsa->local_len - sizeof(int);
WS_getsockname(HANDLE2SOCKET(wsa->accept_socket),
- (struct WS_sockaddr *)(addr + sizeof(int)), &len);
- *(int *)addr = len;
+ (struct WS_sockaddr *)(wsa->name_buf + sizeof(int)), &len);
+ *(int *)wsa->name_buf = len;
+
+ if (wine_uninterrupted_write_memory( (char *)wsa->buf + wsa->data_len,
+ wsa->name_buf, sizeof(int) + len ) < sizeof(int) + len)
+ {
+ status = STATUS_ACCESS_VIOLATION;
+ goto finish;
+ }
- addr += wsa->local_len;
len = wsa->remote_len - sizeof(int);
WS_getpeername(HANDLE2SOCKET(wsa->accept_socket),
- (struct WS_sockaddr *)(addr + sizeof(int)), &len);
- *(int *)addr = len;
+ (struct WS_sockaddr *)(wsa->name_buf + sizeof(int)), &len);
+ *(int *)wsa->name_buf = len;
+
+ if (wine_uninterrupted_write_memory( (char *)wsa->buf + wsa->data_len + wsa->local_len,
+ wsa->name_buf, sizeof(int) + len ) < sizeof(int) + len)
+ {
+ status = STATUS_ACCESS_VIOLATION;
+ goto finish;
+ }
if (!wsa->read)
goto finish;
@@ -2433,7 +2445,8 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW
}
release_sock_fd( acceptor, fd );
- wsa = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa) );
+ wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_accept_async,
+ name_buf[max( local_addr_len, rem_addr_len )]) );
if(!wsa)
{
SetLastError(WSAEFAULT);
--
2.2.2

View File

@@ -1 +1,2 @@
Fixes: Avoid race-conditions of async WSARecv() operations with write watches.
Fixes: Avoid race-conditions with write watches in WS2_async_accept.