diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 22 | 
1 files changed, 17 insertions, 5 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3274ef625dba..b542f14ed444 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2349,6 +2349,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 @@ -2384,18 +2394,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; @@ -3255,6 +3265,8 @@ static int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk)  	peer_port = tsk_peer_port(tsk);  	nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON); +	if (!nest) +		return -EMSGSIZE;  	if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node))  		goto msg_full;  | 
