[PATCH 2/6] ws2_32: Validate address length in bind().

Zebediah Figura zfigura at codeweavers.com
Wed Jul 21 20:34:51 CDT 2021


bind() returns WSAEFAULT for short length, but IOCTL_AFD_BIND returns
STATUS_INVALID_ADDRESS, which translates to WSAEADDRNOTAVAIL.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/ws2_32/socket.c     | 42 +++++++++++++++++++++++++++++++++++++++-
 dlls/ws2_32/tests/sock.c | 10 ++++------
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index fac19355705..88d30cb2802 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1775,12 +1775,52 @@ int WINAPI WS_bind( SOCKET s, const struct WS_sockaddr *addr, int len )
 
     TRACE( "socket %#lx, addr %s\n", s, debugstr_sockaddr(addr) );
 
-    if (!addr || (addr->sa_family && !supported_pf( addr->sa_family )))
+    if (!addr)
     {
         SetLastError( WSAEAFNOSUPPORT );
         return -1;
     }
 
+    switch (addr->sa_family)
+    {
+        case WS_AF_INET:
+            if (len < sizeof(struct WS_sockaddr_in))
+            {
+                SetLastError( WSAEFAULT );
+                return -1;
+            }
+            break;
+
+        case WS_AF_INET6:
+            if (len < sizeof(struct WS_sockaddr_in6))
+            {
+                SetLastError( WSAEFAULT );
+                return -1;
+            }
+            break;
+
+        case WS_AF_IPX:
+            if (len < sizeof(struct WS_sockaddr_ipx))
+            {
+                SetLastError( WSAEFAULT );
+                return -1;
+            }
+            break;
+
+        case WS_AF_IRDA:
+            if (len < sizeof(SOCKADDR_IRDA))
+            {
+                SetLastError( WSAEFAULT );
+                return -1;
+            }
+            break;
+
+        default:
+            FIXME( "unknown protocol %u\n", addr->sa_family );
+            SetLastError( WSAEAFNOSUPPORT );
+            return -1;
+    }
+
     if (!(sync_event = get_sync_event())) return -1;
 
     params = HeapAlloc( GetProcessHeap(), 0, sizeof(int) + len );
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index f5c5acf161e..dd880531047 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -10668,15 +10668,13 @@ static void test_bind(void)
                 ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
 
                 ret = bind(s, unicast_addr->Address.lpSockaddr, sizeof(struct sockaddr_in6_old));
-                todo_wine_if (!addr6.sin6_scope_id)
-                {
-                    ok(ret == -1, "expected failure\n");
-                    ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
-                }
+                ok(ret == -1, "expected failure\n");
+                ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
 
                 addr6.sin6_scope_id = 0xabacab;
                 ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
-                ok(ret == -1, "expected failure\n");
+                todo_wine_if (!((const struct sockaddr_in6 *)unicast_addr->Address.lpSockaddr)->sin6_scope_id)
+                    ok(ret == -1, "expected failure\n");
                 todo_wine ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
 
                 addr6.sin6_scope_id = 0;
-- 
2.30.2




More information about the wine-devel mailing list