[PATCH 4/5] ntdll: Error out when trying to use a UDP-only option on a TCP socket

Alex Henrie alexhenrie24 at gmail.com
Fri Aug 13 00:56:16 CDT 2021


Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
 dlls/ntdll/unix/socket.c | 26 ++++++++++++++++++++++++++
 dlls/ws2_32/socket.c     |  1 +
 2 files changed, 27 insertions(+)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 1ac4365c012..4523ded1be7 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -1200,6 +1200,14 @@ static NTSTATUS do_setsockopt( HANDLE handle, IO_STATUS_BLOCK *io, int level,
 }
 
 
+static BOOL is_datagram_socket( HANDLE handle, IO_STATUS_BLOCK *io )
+{
+    int sock_type = -1;
+    do_getsockopt( handle, io, SOL_SOCKET, SO_TYPE, &sock_type, sizeof(sock_type) );
+    return sock_type == SOCK_DGRAM;
+}
+
+
 NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io,
                      ULONG code, void *in_buffer, ULONG in_size, void *out_buffer, ULONG out_size )
 {
@@ -1767,18 +1775,23 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
 #endif
 
         case IOCTL_AFD_WINE_GET_IP_MULTICAST_IF:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IP, IP_MULTICAST_IF, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IP_MULTICAST_IF:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IP, IP_MULTICAST_IF, in_buffer, in_size );
 
         case IOCTL_AFD_WINE_GET_IP_MULTICAST_LOOP:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IP, IP_MULTICAST_LOOP, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IP_MULTICAST_LOOP:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IP, IP_MULTICAST_LOOP, in_buffer, in_size );
 
         case IOCTL_AFD_WINE_GET_IP_MULTICAST_TTL:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IP, IP_MULTICAST_TTL, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IP_MULTICAST_TTL:
@@ -1792,15 +1805,19 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
 
 #ifdef IP_PKTINFO
         case IOCTL_AFD_WINE_GET_IP_PKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IP, IP_PKTINFO, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IP_PKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IP, IP_PKTINFO, in_buffer, in_size );
 #elif defined(IP_RECVDSTADDR)
         case IOCTL_AFD_WINE_GET_IP_PKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IP, IP_RECVDSTADDR, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IP_PKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IP, IP_RECVDSTADDR, in_buffer, in_size );
 #endif
 
@@ -1890,18 +1907,21 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
 #endif
 
         case IOCTL_AFD_WINE_GET_IPV6_MULTICAST_HOPS:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_MULTICAST_HOPS:
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, in_buffer, in_size );
 
         case IOCTL_AFD_WINE_GET_IPV6_MULTICAST_IF:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_MULTICAST_IF, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_MULTICAST_IF:
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_MULTICAST_IF, in_buffer, in_size );
 
         case IOCTL_AFD_WINE_GET_IPV6_MULTICAST_LOOP:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_MULTICAST_LOOP:
@@ -1909,25 +1929,31 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
 
 #ifdef IPV6_RECVHOPLIMIT
         case IOCTL_AFD_WINE_GET_IPV6_RECVHOPLIMIT:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_RECVHOPLIMIT:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, in_buffer, in_size );
 #endif
 
 #ifdef IPV6_RECVPKTINFO
         case IOCTL_AFD_WINE_GET_IPV6_RECVPKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVPKTINFO, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_RECVPKTINFO:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVPKTINFO, in_buffer, in_size );
 #endif
 
 #ifdef IPV6_RECVTCLASS
         case IOCTL_AFD_WINE_GET_IPV6_RECVTCLASS:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVTCLASS, out_buffer, out_size );
 
         case IOCTL_AFD_WINE_SET_IPV6_RECVTCLASS:
+            if (!is_datagram_socket( handle, io )) return STATUS_INVALID_PARAMETER;
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVTCLASS, in_buffer, in_size );
 #endif
 
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index c1bbfe4d775..b6e6c53f3d3 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -438,6 +438,7 @@ static DWORD NtStatusToWSAError( NTSTATUS status )
         {STATUS_ACCESS_VIOLATION,           WSAEFAULT},
         {STATUS_PAGEFILE_QUOTA,             WSAENOBUFS},
         {STATUS_INVALID_HANDLE,             WSAENOTSOCK},
+        {STATUS_INVALID_PARAMETER,          WSAEINVAL},
         {STATUS_NO_SUCH_DEVICE,             WSAENETDOWN},
         {STATUS_NO_SUCH_FILE,               WSAENETDOWN},
         {STATUS_NO_MEMORY,                  WSAENOBUFS},
-- 
2.32.0




More information about the wine-devel mailing list