diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/discover.c | 5 | ||||
| -rw-r--r-- | net/tipc/topsrv.c | 20 | 
2 files changed, 15 insertions, 10 deletions
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index e8630707901e..e8dcdf267c0c 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,  	u32 self;  	int err; -	skb_linearize(skb); +	if (skb_linearize(skb)) { +		kfree_skb(skb); +		return; +	}  	hdr = buf_msg(skb);  	if (caps & TIPC_NODE_ID128) diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index d92ec92f0b71..e3b427a70398 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)  	conn_put(con);  } -static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s) +static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)  {  	struct tipc_conn *con;  	int ret; @@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)  	}  	con->conid = ret;  	s->idr_in_use++; -	spin_unlock_bh(&s->idr_lock);  	set_bit(CF_CONNECTED, &con->flags);  	con->server = s; +	con->sock = sock; +	conn_get(con); +	spin_unlock_bh(&s->idr_lock);  	return con;  } @@ -467,7 +469,7 @@ static void tipc_topsrv_accept(struct work_struct *work)  		ret = kernel_accept(lsock, &newsock, O_NONBLOCK);  		if (ret < 0)  			return; -		con = tipc_conn_alloc(srv); +		con = tipc_conn_alloc(srv, newsock);  		if (IS_ERR(con)) {  			ret = PTR_ERR(con);  			sock_release(newsock); @@ -479,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)  		newsk->sk_data_ready = tipc_conn_data_ready;  		newsk->sk_write_space = tipc_conn_write_space;  		newsk->sk_user_data = con; -		con->sock = newsock;  		write_unlock_bh(&newsk->sk_callback_lock);  		/* Wake up receive process in case of 'SYN+' message */  		newsk->sk_data_ready(newsk); +		conn_put(con);  	}  } @@ -577,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,  	sub.filter = filter;  	*(u64 *)&sub.usr_handle = (u64)port; -	con = tipc_conn_alloc(tipc_topsrv(net)); +	con = tipc_conn_alloc(tipc_topsrv(net), NULL);  	if (IS_ERR(con))  		return false;  	*conid = con->conid; -	con->sock = NULL;  	rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub); -	if (rc >= 0) -		return true; +	if (rc) +		conn_put(con); +  	conn_put(con); -	return false; +	return !rc;  }  void tipc_topsrv_kern_unsubscr(struct net *net, int conid)  | 
