Module: wine Branch: master Commit: c722d819eac5987bd0659c3e9b9fe2f4392cb501 URL: https://source.winehq.org/git/wine.git/?a=commit;h=c722d819eac5987bd0659c3e9...
Author: Damjan Jovanovic damjan.jov@gmail.com Date: Thu Aug 1 06:11:32 2019 +0200
ws2_32: Avoid data corruption of WSAPROTOCOL_INFO in ws_protocol_info().
WS_EnterSingleProtocol[A/W]() fills WSAPROTOCOL_INFO with zeroes, ovewriting what was already there, so in ws_protocol_info(), populate the address family, socket type and protocol only AFTER calling it.
Signed-off-by: Damjan Jovanovic damjan.jov@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ws2_32/socket.c | 16 +++++++++++----- dlls/ws2_32/tests/sock.c | 5 ++--- 2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 0034787..d82172a 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2328,6 +2328,9 @@ static INT WS_EnumProtocols( BOOL unicode, const INT *protocols, LPWSAPROTOCOL_I static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size) { NTSTATUS status; + int address_family; + int socket_type; + int protocol;
*size = unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA); memset(buffer, 0, *size); @@ -2338,9 +2341,9 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i status = wine_server_call( req ); if (!status) { - buffer->iAddressFamily = convert_af_u2w(reply->family); - buffer->iSocketType = convert_socktype_u2w(reply->type); - buffer->iProtocol = convert_proto_u2w(reply->protocol); + address_family = convert_af_u2w(reply->family); + socket_type = convert_socktype_u2w(reply->type); + protocol = convert_proto_u2w(reply->protocol); } } SERVER_END_REQ; @@ -2353,9 +2356,12 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i }
if (unicode) - WS_EnterSingleProtocolW( buffer->iProtocol, buffer); + WS_EnterSingleProtocolW( protocol, buffer); else - WS_EnterSingleProtocolA( buffer->iProtocol, (WSAPROTOCOL_INFOA *)buffer); + WS_EnterSingleProtocolA( protocol, (WSAPROTOCOL_INFOA *)buffer); + buffer->iAddressFamily = address_family; + buffer->iSocketType = socket_type; + buffer->iProtocol = protocol;
return TRUE; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 03f4e68..e97cd38 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1668,9 +1668,8 @@ todo_wine "SO_PROTOCOL_INFO[A/W] comparison failed\n");
/* Remove IF when WSAEnumProtocols support IPV6 data */ - todo_wine_if (prottest[i].family == AF_INET6) - ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n", - prottest[i].family, infoA.iAddressFamily); + ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n", + prottest[i].family, infoA.iAddressFamily); ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n", prottest[i].type, infoA.iSocketType); ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",