[RFC PATCH 10/11] ntdll: Don't call try_recv before server call in sock_recv.

Jinoh Kang jinoh.kang.kr at gmail.com
Sat Jan 22 07:00:35 CST 2022


Otherwise, try_recv() call from sock_recv() may race against try_recv()
call from async_recv_proc(), shuffling the packet order.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52401
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---

Notes:
    Patch split as per review feedback:
    https://www.winehq.org/pipermail/wine-devel/2022-January/204710.html

 dlls/ntdll/unix/socket.c | 16 +++-------------
 dlls/ws2_32/tests/sock.c |  8 ++++----
 2 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 3ab3c55d6e4..a5f808c265d 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -684,7 +684,6 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
                            struct WS_sockaddr *addr, int *addr_len, DWORD *ret_flags, int unix_flags, int force_async )
 {
     struct async_recv_ioctl *async;
-    ULONG_PTR information;
     HANDLE wait_handle;
     DWORD async_size;
     NTSTATUS status;
@@ -741,22 +740,13 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
         }
     }
 
-    status = try_recv( fd, async, &information );
-
-    if (status != STATUS_SUCCESS && status != STATUS_BUFFER_OVERFLOW && status != STATUS_DEVICE_NOT_READY)
-    {
-        release_fileio( &async->io );
-        return status;
-    }
-
-    if (status == STATUS_DEVICE_NOT_READY && force_async)
-        status = STATUS_PENDING;
+    status = force_async ? STATUS_PENDING : STATUS_DEVICE_NOT_READY;
 
     memset( &inline_apc, 0, sizeof(inline_apc) );
     SERVER_START_REQ( recv_socket )
     {
         req->status = status;
-        req->total  = information;
+        req->total  = 0;
         req->async  = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
         req->oob    = !!(unix_flags & MSG_OOB);
         wine_server_set_reply( req, &inline_apc, sizeof(inline_apc) );
@@ -766,7 +756,7 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
         if ((!NT_ERROR(status) || wait_handle) && !is_completion_deferred( status ))
         {
             io->Status = status;
-            io->Information = information;
+            io->Information = 0;
         }
     }
     SERVER_END_REQ;
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 054e597b719..4199676f460 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -7750,8 +7750,8 @@ static void test_shutdown(void)
 
     WSASetLastError(0xdeadbeef);
     ret = recv(server, buffer, sizeof(buffer), 0);
-    todo_wine ok(ret == -1, "got %d\n", ret);
-    todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
+    ok(ret == -1, "got %d\n", ret);
+    ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
 
     ret = send(server, "test", 5, 0);
     ok(ret == 5, "got %d\n", ret);
@@ -7845,8 +7845,8 @@ static void test_shutdown(void)
 
     WSASetLastError(0xdeadbeef);
     ret = recv(server, buffer, sizeof(buffer), 0);
-    todo_wine ok(ret == -1, "got %d\n", ret);
-    todo_wine ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
+    ok(ret == -1, "got %d\n", ret);
+    ok(WSAGetLastError() == WSAESHUTDOWN, "got error %u\n", WSAGetLastError());
 
     WSASetLastError(0xdeadbeef);
     ret = send(server, "test", 5, 0);
-- 
2.31.1




More information about the wine-devel mailing list