mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net/smc: reduce sock_put() for fallback sockets
smc_release() calls a sock_put() for smc fallback sockets to cover
the passive closing sock_hold() in __smc_connect() and
smc_tcp_listen_work(). This does not make sense for sockets in state
SMC_LISTEN and SMC_INIT.
An SMC socket stays in state SMC_INIT if connect fails. The sock_put
in smc_connect_abort() does not cover all failures. Move it into
smc_connect_decline_fallback().
Fixes: ee9dfbef02 ("net/smc: handle sockopts forcing fallback")
Reported-by: syzbot+3a0748c8f2f210c0ef9b@syzkaller.appspotmail.com
Reported-by: syzbot+9e60d2428a42049a592a@syzkaller.appspotmail.com
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									000244d3dc
								
							
						
					
					
						commit
						e1bbdd5704
					
				
					 2 changed files with 12 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -147,7 +147,8 @@ static int smc_release(struct socket *sock)
 | 
			
		|||
		smc->clcsock = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (smc->use_fallback) {
 | 
			
		||||
		sock_put(sk); /* passive closing */
 | 
			
		||||
		if (sk->sk_state != SMC_LISTEN && sk->sk_state != SMC_INIT)
 | 
			
		||||
			sock_put(sk); /* passive closing */
 | 
			
		||||
		sk->sk_state = SMC_CLOSED;
 | 
			
		||||
		sk->sk_state_change(sk);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -417,12 +418,18 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code)
 | 
			
		|||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	if (reason_code < 0) /* error, fallback is not possible */
 | 
			
		||||
	if (reason_code < 0) { /* error, fallback is not possible */
 | 
			
		||||
		if (smc->sk.sk_state == SMC_INIT)
 | 
			
		||||
			sock_put(&smc->sk); /* passive closing */
 | 
			
		||||
		return reason_code;
 | 
			
		||||
	}
 | 
			
		||||
	if (reason_code != SMC_CLC_DECL_REPLY) {
 | 
			
		||||
		rc = smc_clc_send_decline(smc, reason_code);
 | 
			
		||||
		if (rc < 0)
 | 
			
		||||
		if (rc < 0) {
 | 
			
		||||
			if (smc->sk.sk_state == SMC_INIT)
 | 
			
		||||
				sock_put(&smc->sk); /* passive closing */
 | 
			
		||||
			return rc;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return smc_connect_fallback(smc);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -435,8 +442,6 @@ static int smc_connect_abort(struct smc_sock *smc, int reason_code,
 | 
			
		|||
		smc_lgr_forget(smc->conn.lgr);
 | 
			
		||||
	mutex_unlock(&smc_create_lgr_pending);
 | 
			
		||||
	smc_conn_free(&smc->conn);
 | 
			
		||||
	if (reason_code < 0 && smc->sk.sk_state == SMC_INIT)
 | 
			
		||||
		sock_put(&smc->sk); /* passive closing */
 | 
			
		||||
	return reason_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,6 +107,8 @@ static void smc_close_active_abort(struct smc_sock *smc)
 | 
			
		|||
	}
 | 
			
		||||
	switch (sk->sk_state) {
 | 
			
		||||
	case SMC_INIT:
 | 
			
		||||
		sk->sk_state = SMC_PEERABORTWAIT;
 | 
			
		||||
		break;
 | 
			
		||||
	case SMC_ACTIVE:
 | 
			
		||||
		sk->sk_state = SMC_PEERABORTWAIT;
 | 
			
		||||
		release_sock(sk);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue