tipc: allow service ranges to be connect()'ed on RDM/DGRAM
authorErik Hugne <erik.hugne@gmail.com>
Sun, 17 Mar 2019 17:46:42 +0000 (18:46 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2019 04:26:18 +0000 (06:26 +0200)
[ Upstream commit ea239314fe42ace880bdd834256834679346c80e ]

We move the check that prevents connecting service ranges to after
the RDM/DGRAM check, and move address sanity control to a separate
function that also validates the service range.

Fixes: 23998835be98 ("tipc: improve address sanity check in tipc_connect()")
Signed-off-by: Erik Hugne <erik.hugne@gmail.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/tipc/socket.c

index 88c307e..67a7b31 100644 (file)
@@ -2310,6 +2310,16 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)
        return 0;
 }
 
+static bool tipc_sockaddr_is_sane(struct sockaddr_tipc *addr)
+{
+       if (addr->family != AF_TIPC)
+               return false;
+       if (addr->addrtype == TIPC_SERVICE_RANGE)
+               return (addr->addr.nameseq.lower <= addr->addr.nameseq.upper);
+       return (addr->addrtype == TIPC_SERVICE_ADDR ||
+               addr->addrtype == TIPC_SOCKET_ADDR);
+}
+
 /**
  * tipc_connect - establish a connection to another TIPC port
  * @sock: socket structure
@@ -2345,18 +2355,18 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
                if (!tipc_sk_type_connectionless(sk))
                        res = -EINVAL;
                goto exit;
-       } else if (dst->family != AF_TIPC) {
-               res = -EINVAL;
        }
-       if (dst->addrtype != TIPC_ADDR_ID && dst->addrtype != TIPC_ADDR_NAME)
+       if (!tipc_sockaddr_is_sane(dst)) {
                res = -EINVAL;
-       if (res)
                goto exit;
-
+       }
        /* DGRAM/RDM connect(), just save the destaddr */
        if (tipc_sk_type_connectionless(sk)) {
                memcpy(&tsk->peer, dest, destlen);
                goto exit;
+       } else if (dst->addrtype == TIPC_SERVICE_RANGE) {
+               res = -EINVAL;
+               goto exit;
        }
 
        previous = sk->sk_state;