Browse Source

Network address domains should match socket domain.

For functions like connect(), bind(), and sendto(), the supplied network
address's domain (a.k.a. family) should match the domain of the socket.
This was not being checked consistently for all routines and, if present,
was a hard-coded check for IPv4. This changes makes these checks more
generic and removes a few other IPv4 specific checks.

For the send() case, the checks are made in the protocol routines rather
than the netcore entry point or at the network layer. The protocol send
routines are in charge of copying the remote address out of the parameters
(typicall a copy from user mode), so the checks are performed as close to
the copy as possible.
Chris Stevens 6 years ago
parent
commit
b31c7f8f2f

+ 0 - 3
apps/libc/dynamic/socket.c

@@ -663,9 +663,6 @@ Return Value:
         } else if (Status == STATUS_TIMEOUT) {
             errno = ETIMEDOUT;
 
-        } else if (Status == STATUS_UNEXPECTED_TYPE) {
-            errno = EAFNOSUPPORT;
-
         } else {
             errno = ClConvertKstatusToErrorNumber(Status);
         }

+ 2 - 8
drivers/net/netcore/addr.c

@@ -1904,6 +1904,8 @@ Return Value:
     ASSERT((LocalInformation != NULL) || (RemoteAddress != NULL));
     ASSERT((BindingType == SocketFullyBound) || (LocalInformation != NULL));
     ASSERT((BindingType != SocketFullyBound) || (RemoteAddress != NULL));
+    ASSERT((RemoteAddress == NULL) ||
+           (RemoteAddress->Domain == Socket->KernelSocket.Domain));
 
     LockHeld = FALSE;
     Protocol = Socket->Protocol;
@@ -2949,15 +2951,7 @@ Return Value:
         return STATUS_INVALID_PARAMETER;
     }
 
-    //
-    // Currently only IPv4 is supported.
-    //
-
     Domain = Information->Domain;
-    if (Domain != NetDomainIp4) {
-        return STATUS_INVALID_CONFIGURATION;
-    }
-
     KeAcquireQueuedLock(Link->QueuedLock);
 
     //

+ 1 - 0
drivers/net/netcore/ip4.c

@@ -1139,6 +1139,7 @@ Return Value:
     ULONG TimeToLive;
     ULONG TotalLength;
 
+    ASSERT(Destination->Domain == Socket->KernelSocket.Domain);
     ASSERT((Socket->KernelSocket.Type == NetSocketRaw) ||
            (Socket->KernelSocket.Protocol ==
             Socket->Protocol->ParentProtocolNumber));

+ 21 - 2
drivers/net/netcore/netcore.c

@@ -1617,7 +1617,7 @@ Return Value:
     //
     // If the port is non-zero and less than or equal to the maximum port that
     // requires a permission check, make sure the thread as the right
-    // privilege. Some protocols do not have this geneirc port restriction and
+    // privilege. Some protocols do not have this generic port restriction and
     // can opt out of the check.
     //
 
@@ -1633,6 +1633,15 @@ Return Value:
         }
     }
 
+    //
+    // The address's domain must match the socket's domain.
+    //
+
+    if (Address->Domain != Socket->Domain) {
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
+        goto BindToAddressEnd;
+    }
+
     Status = NetSocket->Protocol->Interface.BindToAddress(NetSocket,
                                                           Link,
                                                           Address);
@@ -1817,7 +1826,17 @@ Return Value:
         RtlDebugPrint("...\n");
     }
 
-    Status = NetSocket->Protocol->Interface.Connect(NetSocket, Address);
+    //
+    // The remote connection address's domain must match the socket's domain.
+    //
+
+    if (Address->Domain == Socket->Domain) {
+        Status = NetSocket->Protocol->Interface.Connect(NetSocket, Address);
+
+    } else {
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
+    }
+
     if (NetGlobalDebug != FALSE) {
         RtlDebugPrint("Net: Connect socket 0x%x to ", NetSocket);
         NetDebugPrintAddress(Address);

+ 4 - 0
drivers/net/netcore/netlink/generic.c

@@ -1596,6 +1596,10 @@ Return Value:
         }
 
         Destination = &(Socket->RemoteAddress);
+
+    } else if (Destination->Domain != Socket->KernelSocket.Domain) {
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
+        goto GenericSendEnd;
     }
 
     //

+ 7 - 0
drivers/net/netcore/netlink/netlink.c

@@ -778,6 +778,13 @@ Return Value:
 
     NET_RECEIVE_CONTEXT ReceiveContext;
 
+    //
+    // Upper layers should have failed on destination address's that do not
+    // match the socket's domain.
+    //
+
+    ASSERT(Destination->Domain == Socket->KernelSocket.Domain);
+
     ReceiveContext.Link = Socket->Link;
     ReceiveContext.Protocol = Socket->Protocol;
     ReceiveContext.Network = Socket->Network;

+ 4 - 9
drivers/net/netcore/raw.c

@@ -706,15 +706,6 @@ Return Value:
         goto RawBindToAddressEnd;
     }
 
-    //
-    // Currently only IPv4 addresses are supported.
-    //
-
-    if (Address->Domain != NetDomainIp4) {
-        Status = STATUS_NOT_SUPPORTED;
-        goto RawBindToAddressEnd;
-    }
-
     //
     // The port doesn't make a difference on raw sockets. Set it to the
     // protocol value, which is storked in the kernel socket.
@@ -1064,6 +1055,10 @@ Return Value:
         }
 
         Destination = &(Socket->RemoteAddress);
+
+    } else if (Destination->Domain != Socket->KernelSocket.Domain) {
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
+        goto RawSendEnd;
     }
 
     //

+ 0 - 9
drivers/net/netcore/tcp.c

@@ -950,15 +950,6 @@ Return Value:
 
     KSTATUS Status;
 
-    //
-    // Currently only IPv4 addresses are supported.
-    //
-
-    if (Address->Domain != NetDomainIp4) {
-        Status = STATUS_NOT_SUPPORTED;
-        goto TcpBindToAddressEnd;
-    }
-
     //
     // Pass the request down to the network layer.
     //

+ 4 - 9
drivers/net/netcore/udp.c

@@ -676,15 +676,6 @@ Return Value:
         goto UdpBindToAddressEnd;
     }
 
-    //
-    // Currently only IPv4 addresses are supported.
-    //
-
-    if (Address->Domain != NetDomainIp4) {
-        Status = STATUS_NOT_SUPPORTED;
-        goto UdpBindToAddressEnd;
-    }
-
     //
     // Pass the request down to the network layer.
     //
@@ -1002,6 +993,10 @@ Return Value:
         }
 
         Destination = &(Socket->RemoteAddress);
+
+    } else if (Destination->Domain != Socket->KernelSocket.Domain) {
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
+        goto UdpSendEnd;
     }
 
     //

+ 3 - 3
kernel/io/unsocket.c

@@ -1051,7 +1051,7 @@ Return Value:
     UnixSocket = (PUNIX_SOCKET)Socket;
     KeAcquireQueuedLock(UnixSocket->Lock);
     if (Address->Domain != NetDomainLocal) {
-        Status = STATUS_UNEXPECTED_TYPE;
+        Status = STATUS_DOMAIN_NOT_SUPPORTED;
         goto UnixSocketConnectEnd;
     }
 
@@ -1412,7 +1412,7 @@ Return Value:
         }
 
         if (Destination->Domain != NetDomainLocal) {
-            Status = STATUS_UNEXPECTED_TYPE;
+            Status = STATUS_DOMAIN_NOT_SUPPORTED;
             goto UnixSocketSendDataEnd;
         }
 
@@ -1659,7 +1659,7 @@ Return Value:
         KeAcquireQueuedLock(RemoteUnixSocket->Lock);
         if (RemoteUnixSocket->KernelSocket.Type != Socket->Type) {
             KeReleaseQueuedLock(RemoteUnixSocket->Lock);
-            Status = STATUS_UNEXPECTED_TYPE;
+            Status = STATUS_DOMAIN_NOT_SUPPORTED;
             goto UnixSocketSendDataEnd;
         }