[PATCH 1/7] ws2_32: Pre-validate optlen in getsockopt().
Paul Gofman
pgofman at codeweavers.com
Sat Mar 5 13:04:03 CST 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
Supersedes 228827-228832.
For reference, the full patchset (which adds more tests and fixes individual options) is here:
https://github.com/gofman/wine/commits/winsock
dlls/ws2_32/socket.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index e5e29107853..30dc007167a 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1395,11 +1395,18 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
TRACE( "socket %#Ix, %s, optval %p, optlen %p (%d)\n",
s, debugstr_sockopt(level, optname), optval, optlen, optlen ? *optlen : 0 );
- if ((level != SOL_SOCKET || optname != SO_OPENTYPE) &&
- !socket_list_find( s ))
+ if ((level != SOL_SOCKET || optname != SO_OPENTYPE))
{
- SetLastError( WSAENOTSOCK );
- return SOCKET_ERROR;
+ if (!socket_list_find( s ))
+ {
+ SetLastError( WSAENOTSOCK );
+ return SOCKET_ERROR;
+ }
+ if (!optlen || *optlen <= 0)
+ {
+ SetLastError( WSAEFAULT );
+ return -1;
+ }
}
switch(level)
@@ -1464,7 +1471,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
}
case SO_CONNECT_TIME:
- if (!optlen || !optval)
+ if (!optval)
{
SetLastError( WSAEFAULT );
return -1;
@@ -1483,7 +1490,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
int len = sizeof(linger);
int ret;
- if (!optlen || *optlen < sizeof(BOOL)|| !optval)
+ if (*optlen < sizeof(BOOL)|| !optval)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
@@ -1500,7 +1507,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
/* As mentioned in setsockopt, Windows ignores this, so we
* always return true here */
case SO_DONTROUTE:
- if (!optlen || *optlen < sizeof(BOOL) || !optval)
+ if (*optlen < sizeof(BOOL) || !optval)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
@@ -1521,7 +1528,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
int size;
/* struct linger and LINGER have different sizes */
- if (!optlen || *optlen < sizeof(LINGER) || !optval)
+ if (*optlen < sizeof(LINGER) || !optval)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
@@ -1540,7 +1547,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
}
case SO_MAX_MSG_SIZE:
- if (!optlen || *optlen < sizeof(int) || !optval)
+ if (*optlen < sizeof(int) || !optval)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
@@ -1574,9 +1581,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
ret = ws_protocol_info(s, optname == SO_PROTOCOL_INFOW, &infow, &size);
if (ret)
{
- if (!optlen || !optval || *optlen < size)
+ if (!optval || *optlen < size)
{
- if(optlen) *optlen = size;
+ *optlen = size;
ret = 0;
SetLastError(WSAEFAULT);
}
@@ -1606,7 +1613,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
WSAPROTOCOL_INFOW info;
int size;
- if (!optlen || *optlen < sizeof(int) || !optval)
+ if (*optlen < sizeof(int) || !optval)
{
SetLastError(WSAEFAULT);
return SOCKET_ERROR;
@@ -1765,7 +1772,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_MULTICAST_LOOP, optval, optlen );
case IPV6_PROTECTION_LEVEL:
- if (!optlen || *optlen < sizeof(UINT) || !optval)
+ if (*optlen < sizeof(UINT) || !optval)
{
SetLastError( WSAEFAULT );
return -1;
--
2.35.1
More information about the wine-devel
mailing list