[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