ws2_32: Fix buffer size check in WSAIoctl() for SIO_GET_INTERFACE_LIST.

Fixes out of bound memory access in Anno 1404 Addon.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2020-12-16 11:58:27 +03:00 committed by Alexandre Julliard
parent ebb8a59d81
commit f17404f8ed
2 changed files with 27 additions and 1 deletions

View File

@ -4618,10 +4618,11 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
if (ptr->IpAddressList.IpAddress.String[0] == '\0')
continue;
if ((numInt + 1)*sizeof(INTERFACE_INFO)/sizeof(IP_ADAPTER_INFO) > out_size)
if ((numInt + 1) * sizeof(INTERFACE_INFO) > out_size)
{
WARN("Buffer too small = %u, out_size = %u\n", numInt + 1, out_size);
status = WSAEFAULT;
if (ret_size) *ret_size = 0;
break;
}

View File

@ -10514,6 +10514,30 @@ static void test_WSCGetProviderPath(void)
ok(len == 256, "Got unexpected len %d.\n", len);
}
static void test_wsaioctl(void)
{
char buffer[4096];
DWORD size;
SOCKET s;
int ret;
s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
size = 0xdeadbeef;
ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL);
ok(!ret, "Got unexpected ret %d.\n", ret);
ok(size && size != 0xdeadbeef && !(size % sizeof(INTERFACE_INFO)), "Got unexpected size %u.\n", size);
size = 0xdeadbeef;
ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO), &size, NULL, NULL);
ok(ret == -1, "Got unexpected ret %d.\n", ret);
ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
ok(!size, "Got unexpected size %u.\n", size);
closesocket(s);
}
START_TEST( sock )
{
int i;
@ -10595,6 +10619,7 @@ START_TEST( sock )
/* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */
test_send();
test_synchronous_WSAIoctl();
test_wsaioctl();
Exit();
}