Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 14 +++++++++++++- dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 31e8be5b6b0..1a0d28c484e 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1525,6 +1525,12 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_ERROR, optval, optlen );
case SO_KEEPALIVE: + if (*optlen < 1 || !optval) + { + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } + *optlen = 1; return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_KEEPALIVE, optval, optlen );
case SO_LINGER: @@ -2827,7 +2833,13 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return -1;
case SO_KEEPALIVE: - return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_KEEPALIVE, optval, optlen ); + if (optlen <= 0 || !optval) + { + SetLastError( optlen ? WSAENOBUFS : WSAEFAULT ); + return SOCKET_ERROR; + } + value = *optval; + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_KEEPALIVE, (char *)&value, sizeof(value) );
case SO_LINGER: return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_LINGER, optval, optlen ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 3da68b0e4a8..a6505134d44 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1171,6 +1171,7 @@ static void test_set_getsockopt(void) { {AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTLINGER, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 8 +++++++- dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 1a0d28c484e..342c3803c67 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1541,7 +1541,8 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl /* struct linger and LINGER have different sizes */ if (*optlen < sizeof(LINGER) || !optval) { - SetLastError(WSAEFAULT); + if (optval) memset( optval, 0, *optlen ); + SetLastError( WSAEFAULT ); return SOCKET_ERROR; }
@@ -2842,6 +2843,11 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_KEEPALIVE, (char *)&value, sizeof(value) );
case SO_LINGER: + if (optlen < sizeof(LINGER) || !optval) + { + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_LINGER, optval, optlen );
case SO_OOBINLINE: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index a6505134d44..ccc1cca06db 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1171,6 +1171,7 @@ static void test_set_getsockopt(void) { {AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTLINGER, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_LINGER, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 12 ++++++++++-- dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 342c3803c67..85387f08c59 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1570,7 +1570,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return 0;
case SO_OOBINLINE: - return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_OOBINLINE, optval, optlen ); + ret = server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_OOBINLINE, optval, optlen ); + if (!ret && *optlen < sizeof(DWORD)) *optlen = 1; + return ret;
/* SO_OPENTYPE does not require a valid socket handle. */ case SO_OPENTYPE: @@ -2851,7 +2853,13 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_LINGER, optval, optlen );
case SO_OOBINLINE: - return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_OOBINLINE, optval, optlen ); + if (!optval) + { + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } + memcpy( &value, optval, min( optlen, sizeof(value) )); + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_OOBINLINE, (char *)&value, sizeof(value) );
case SO_RCVBUF: return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_RCVBUF, optval, optlen ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index ccc1cca06db..104129189e4 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1172,6 +1172,7 @@ static void test_set_getsockopt(void) {AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTLINGER, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_LINGER, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OOBINLINE, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110138
Your paranoid android.
=== debian11 (32 bit Arabic:Morocco report) ===
ws2_32: sock.c:5935: Test succeeded inside todo block: expected timeout
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 6 ++++-- dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 85387f08c59..f440d7b0abd 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1578,12 +1578,13 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl case SO_OPENTYPE: if (!optlen || *optlen < sizeof(int) || !optval) { - SetLastError(WSAEFAULT); + SetLastError( WSAEFAULT ); return SOCKET_ERROR; } *(int *)optval = get_per_thread_data()->opentype; *optlen = sizeof(int); TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) ); + SetLastError( ERROR_SUCCESS ); return 0;
case SO_PROTOCOL_INFOA: @@ -2917,11 +2918,12 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int case SO_OPENTYPE: if (!optlen || optlen < sizeof(int) || !optval) { - SetLastError(WSAEFAULT); + SetLastError( WSAEFAULT ); return SOCKET_ERROR; } get_per_thread_data()->opentype = *(const int *)optval; TRACE("setting global SO_OPENTYPE = 0x%x\n", *((const int*)optval) ); + SetLastError( ERROR_SUCCESS ); return 0;
case SO_RANDOMIZE_PORT: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 104129189e4..7d0fd60522f 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1177,6 +1177,7 @@ static void test_set_getsockopt(void) {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OPENTYPE, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE}, {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_TTL, TRUE, {1, 1, 4}, {0}, FALSE}, {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TOS, TRUE, {1, 1, 4}, {0}, FALSE},
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110139
Your paranoid android.
=== debian11 (32 bit Chinese:China report) ===
ws2_32: sock.c:5529: Test failed: expected timeout sock.c:5936: Test succeeded inside todo block: expected timeout
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 7 +++++++ dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 8 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index f440d7b0abd..58bb332e5ca 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1609,6 +1609,12 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl }
case SO_RCVBUF: + if (*optlen < sizeof(DWORD) || !optval) + { + if (optval) memset( optval, 0, *optlen ); + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_RCVBUF, optval, optlen );
case SO_RCVTIMEO: @@ -2863,6 +2869,7 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_OOBINLINE, (char *)&value, sizeof(value) );
case SO_RCVBUF: + if (optlen < 0) optlen = 4; return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_RCVBUF, optval, optlen );
case SO_RCVTIMEO: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 7d0fd60522f..dde33dc4403 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1173,6 +1173,7 @@ static void test_set_getsockopt(void) {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTLINGER, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_LINGER, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OOBINLINE, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVBUF, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 12 ++++++++++-- dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 58bb332e5ca..e47e6212d45 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1621,7 +1621,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_RCVTIMEO, optval, optlen );
case SO_REUSEADDR: - return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_REUSEADDR, optval, optlen ); + ret = server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_REUSEADDR, optval, optlen ); + if (!ret && *optlen < sizeof(DWORD)) *optlen = 1; + return ret;
case SO_SNDBUF: return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_SNDBUF, optval, optlen ); @@ -2877,7 +2879,13 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_RCVTIMEO, optval, optlen );
case SO_REUSEADDR: - return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_REUSEADDR, optval, optlen ); + if (!optval) + { + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } + memcpy( &value, optval, min( optlen, sizeof(value) )); + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_REUSEADDR, (char *)&value, sizeof(value) );
case SO_SNDBUF: return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_SNDBUF, optval, optlen ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index dde33dc4403..879f03d2e42 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1177,6 +1177,7 @@ static void test_set_getsockopt(void) {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OPENTYPE, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 7 +++++++ dlls/ws2_32/tests/sock.c | 1 + 2 files changed, 8 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e47e6212d45..9f140a6ee44 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1626,6 +1626,12 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl return ret;
case SO_SNDBUF: + if (*optlen < sizeof(DWORD) || !optval) + { + if (optval) memset( optval, 0, *optlen ); + SetLastError( WSAEFAULT ); + return SOCKET_ERROR; + } return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_SNDBUF, optval, optlen );
case SO_SNDTIMEO: @@ -2888,6 +2894,7 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_REUSEADDR, (char *)&value, sizeof(value) );
case SO_SNDBUF: + if (optlen < 0) optlen = 4; return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_SNDBUF, optval, optlen );
case SO_SNDTIMEO: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 879f03d2e42..a0bbde875d3 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1178,6 +1178,7 @@ static void test_set_getsockopt(void) {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE}, + {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDBUF, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OPENTYPE, FALSE, {1, 2, 4}, {0}, TRUE}, {AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_MULTICAST_LOOP, TRUE, {1, 1, 4}, {0}, TRUE, TRUE},
Signed-off-by: Zebediah Figura zfigura@codeweavers.com