diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 47 | 
1 files changed, 34 insertions, 13 deletions
| diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3274ef625dba..145e4decb0c9 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -485,6 +485,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,  		tsk_set_unreturnable(tsk, true);  		if (sock->type == SOCK_DGRAM)  			tsk_set_unreliable(tsk, true); +		__skb_queue_head_init(&tsk->mc_method.deferredq);  	}  	trace_tipc_sk_create(sk, NULL, TIPC_DUMP_NONE, " "); @@ -582,6 +583,7 @@ static int tipc_release(struct socket *sock)  	sk->sk_shutdown = SHUTDOWN_MASK;  	tipc_sk_leave(tsk);  	tipc_sk_withdraw(tsk, 0, NULL); +	__skb_queue_purge(&tsk->mc_method.deferredq);  	sk_stop_timer(sk, &sk->sk_timer);  	tipc_sk_remove(tsk); @@ -2149,6 +2151,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,  	struct tipc_msg *hdr = buf_msg(skb);  	struct net *net = sock_net(sk);  	struct sk_buff_head inputq; +	int mtyp = msg_type(hdr);  	int limit, err = TIPC_OK;  	trace_tipc_sk_filter_rcv(sk, skb, TIPC_DUMP_ALL, " "); @@ -2162,6 +2165,9 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,  	if (unlikely(grp))  		tipc_group_filter_msg(grp, &inputq, xmitq); +	if (unlikely(!grp) && mtyp == TIPC_MCAST_MSG) +		tipc_mcast_filter_msg(net, &tsk->mc_method.deferredq, &inputq); +  	/* Validate and add to receive buffer if there is space */  	while ((skb = __skb_dequeue(&inputq))) {  		hdr = buf_msg(skb); @@ -2349,6 +2355,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 +2400,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; @@ -3054,6 +3070,9 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,  	case TIPC_SOCK_RECVQ_DEPTH:  		value = skb_queue_len(&sk->sk_receive_queue);  		break; +	case TIPC_SOCK_RECVQ_USED: +		value = sk_rmem_alloc_get(sk); +		break;  	case TIPC_GROUP_JOIN:  		seq.type = 0;  		if (tsk->group) @@ -3254,7 +3273,9 @@ static int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk)  	peer_node = tsk_peer_node(tsk);  	peer_port = tsk_peer_port(tsk); -	nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON); +	nest = nla_nest_start_noflag(skb, TIPC_NLA_SOCK_CON); +	if (!nest) +		return -EMSGSIZE;  	if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node))  		goto msg_full; @@ -3311,7 +3332,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,  	if (!hdr)  		goto msg_cancel; -	attrs = nla_nest_start(skb, TIPC_NLA_SOCK); +	attrs = nla_nest_start_noflag(skb, TIPC_NLA_SOCK);  	if (!attrs)  		goto genlmsg_cancel; @@ -3416,7 +3437,7 @@ int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct netlink_callback *cb,  	if (!(sk_filter_state & (1 << sk->sk_state)))  		return 0; -	attrs = nla_nest_start(skb, TIPC_NLA_SOCK); +	attrs = nla_nest_start_noflag(skb, TIPC_NLA_SOCK);  	if (!attrs)  		goto msg_cancel; @@ -3434,7 +3455,7 @@ int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct netlink_callback *cb,  			      TIPC_NLA_SOCK_PAD))  		goto attr_msg_cancel; -	stat = nla_nest_start(skb, TIPC_NLA_SOCK_STAT); +	stat = nla_nest_start_noflag(skb, TIPC_NLA_SOCK_STAT);  	if (!stat)  		goto attr_msg_cancel; @@ -3491,7 +3512,7 @@ static int __tipc_nl_add_sk_publ(struct sk_buff *skb,  	if (!hdr)  		goto msg_cancel; -	attrs = nla_nest_start(skb, TIPC_NLA_PUBL); +	attrs = nla_nest_start_noflag(skb, TIPC_NLA_PUBL);  	if (!attrs)  		goto genlmsg_cancel; @@ -3578,9 +3599,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)  		if (!attrs[TIPC_NLA_SOCK])  			return -EINVAL; -		err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, -				       attrs[TIPC_NLA_SOCK], -				       tipc_nl_sock_policy, NULL); +		err = nla_parse_nested_deprecated(sock, TIPC_NLA_SOCK_MAX, +						  attrs[TIPC_NLA_SOCK], +						  tipc_nl_sock_policy, NULL);  		if (err)  			return err; |