Commit 20e2edba authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ws2_32: Pre-validate optlen in getsockopt().

parent 87859352
...@@ -1395,11 +1395,18 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -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", TRACE( "socket %#Ix, %s, optval %p, optlen %p (%d)\n",
s, debugstr_sockopt(level, optname), optval, optlen, optlen ? *optlen : 0 ); s, debugstr_sockopt(level, optname), optval, optlen, optlen ? *optlen : 0 );
if ((level != SOL_SOCKET || optname != SO_OPENTYPE) && if ((level != SOL_SOCKET || optname != SO_OPENTYPE))
!socket_list_find( s ))
{ {
SetLastError( WSAENOTSOCK ); if (!socket_list_find( s ))
return SOCKET_ERROR; {
SetLastError( WSAENOTSOCK );
return SOCKET_ERROR;
}
if (!optlen || *optlen <= 0)
{
SetLastError( WSAEFAULT );
return -1;
}
} }
switch(level) switch(level)
...@@ -1464,7 +1471,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -1464,7 +1471,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
} }
case SO_CONNECT_TIME: case SO_CONNECT_TIME:
if (!optlen || !optval) if (!optval)
{ {
SetLastError( WSAEFAULT ); SetLastError( WSAEFAULT );
return -1; return -1;
...@@ -1483,7 +1490,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -1483,7 +1490,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
int len = sizeof(linger); int len = sizeof(linger);
int ret; int ret;
if (!optlen || *optlen < sizeof(BOOL)|| !optval) if (*optlen < sizeof(BOOL)|| !optval)
{ {
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -1500,7 +1507,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -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 /* As mentioned in setsockopt, Windows ignores this, so we
* always return true here */ * always return true here */
case SO_DONTROUTE: case SO_DONTROUTE:
if (!optlen || *optlen < sizeof(BOOL) || !optval) if (*optlen < sizeof(BOOL) || !optval)
{ {
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -1521,7 +1528,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -1521,7 +1528,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
int size; int size;
/* struct linger and LINGER have different sizes */ /* struct linger and LINGER have different sizes */
if (!optlen || *optlen < sizeof(LINGER) || !optval) if (*optlen < sizeof(LINGER) || !optval)
{ {
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -1540,7 +1547,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -1540,7 +1547,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
} }
case SO_MAX_MSG_SIZE: case SO_MAX_MSG_SIZE:
if (!optlen || *optlen < sizeof(int) || !optval) if (*optlen < sizeof(int) || !optval)
{ {
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -1574,9 +1581,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -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); ret = ws_protocol_info(s, optname == SO_PROTOCOL_INFOW, &infow, &size);
if (ret) if (ret)
{ {
if (!optlen || !optval || *optlen < size) if (!optval || *optlen < size)
{ {
if(optlen) *optlen = size; *optlen = size;
ret = 0; ret = 0;
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
} }
...@@ -1606,7 +1613,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -1606,7 +1613,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
WSAPROTOCOL_INFOW info; WSAPROTOCOL_INFOW info;
int size; int size;
if (!optlen || *optlen < sizeof(int) || !optval) if (*optlen < sizeof(int) || !optval)
{ {
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -1765,7 +1772,7 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl ...@@ -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 ); return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_MULTICAST_LOOP, optval, optlen );
case IPV6_PROTECTION_LEVEL: case IPV6_PROTECTION_LEVEL:
if (!optlen || *optlen < sizeof(UINT) || !optval) if (*optlen < sizeof(UINT) || !optval)
{ {
SetLastError( WSAEFAULT ); SetLastError( WSAEFAULT );
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment