Unverified Commit f1b1f1a6 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!14916 CVE-2024-56641

Merge Pull Request from: @ci-robot 
 
PR sync from: Wang Liang <wangliang74@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/7FN7LVPKV6KSHFWIK7OI4OP5UO3WPETU/ 
D. Wythe (1):
  net/smc: refactoring initialization of smc sock

Wen Gu (1):
  net/smc: initialize close_work early to avoid warning


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IBEAPB 
 
Link:https://gitee.com/openeuler/kernel/pulls/14916

 

Reviewed-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 50e985c0 9e4e48d5
Loading
Loading
Loading
Loading
+49 −41
Original line number Diff line number Diff line
@@ -363,25 +363,15 @@ static void smc_destruct(struct sock *sk)
		return;
}

static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
				   int protocol)
void smc_sk_init(struct net *net, struct sock *sk, int protocol)
{
	struct smc_sock *smc;
	struct proto *prot;
	struct sock *sk;

	prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
	sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
	if (!sk)
		return NULL;
	struct smc_sock *smc = smc_sk(sk);

	sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
	sk->sk_state = SMC_INIT;
	sk->sk_destruct = smc_destruct;
	sk->sk_protocol = protocol;
	WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem));
	WRITE_ONCE(sk->sk_rcvbuf, 2 * READ_ONCE(net->smc.sysctl_rmem));
	smc = smc_sk(sk);
	INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
	INIT_WORK(&smc->connect_work, smc_connect_work);
	INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
@@ -391,6 +381,25 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
	sk->sk_prot->hash(sk);
	mutex_init(&smc->clcsock_release_lock);
	smc_init_saved_callbacks(smc);
	smc->limit_smc_hs = net->smc.limit_smc_hs;
	smc->use_fallback = false; /* assume rdma capability first */
	smc->fallback_rsn = 0;
	smc_close_init(smc);
}

static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
				   int protocol)
{
	struct proto *prot;
	struct sock *sk;

	prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
	sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
	if (!sk)
		return NULL;

	sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
	smc_sk_init(net, sk, protocol);

	return sk;
}
@@ -1291,7 +1300,6 @@ static int smc_connect_rdma(struct smc_sock *smc,
		goto connect_abort;
	}

	smc_close_init(smc);
	smc_rx_init(smc);

	if (ini->first_contact_local) {
@@ -1427,7 +1435,6 @@ static int smc_connect_ism(struct smc_sock *smc,
			goto connect_abort;
		}
	}
	smc_close_init(smc);
	smc_rx_init(smc);
	smc_tx_init(smc);

@@ -2481,7 +2488,6 @@ static void smc_listen_work(struct work_struct *work)
		goto out_decl;

	mutex_lock(&smc_server_lgr_pending);
	smc_close_init(new_smc);
	smc_rx_init(new_smc);
	smc_tx_init(new_smc);

@@ -3306,6 +3312,31 @@ static const struct proto_ops smc_sock_ops = {
	.splice_read	= smc_splice_read,
};

int smc_create_clcsk(struct net *net, struct sock *sk, int family)
{
	struct smc_sock *smc = smc_sk(sk);
	int rc;

	rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
			      &smc->clcsock);
	if (rc) {
		sk_common_release(sk);
		return rc;
	}

	/* smc_clcsock_release() does not wait smc->clcsock->sk's
	 * destruction;  its sk_state might not be TCP_CLOSE after
	 * smc->sk is close()d, and TCP timers can be fired later,
	 * which need net ref.
	 */
	sk = smc->clcsock->sk;
	__netns_tracker_free(net, &sk->ns_tracker, false);
	sk->sk_net_refcnt = 1;
	get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
	sock_inuse_add(net, 1);
	return 0;
}

static int __smc_create(struct net *net, struct socket *sock, int protocol,
			int kern, struct socket *clcsock)
{
@@ -3331,35 +3362,12 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,

	/* create internal TCP socket for CLC handshake and fallback */
	smc = smc_sk(sk);
	smc->use_fallback = false; /* assume rdma capability first */
	smc->fallback_rsn = 0;

	/* default behavior from limit_smc_hs in every net namespace */
	smc->limit_smc_hs = net->smc.limit_smc_hs;

	rc = 0;
	if (!clcsock) {
		rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
				      &smc->clcsock);
		if (rc) {
			sk_common_release(sk);
			goto out;
		}

		/* smc_clcsock_release() does not wait smc->clcsock->sk's
		 * destruction;  its sk_state might not be TCP_CLOSE after
		 * smc->sk is close()d, and TCP timers can be fired later,
		 * which need net ref.
		 */
		sk = smc->clcsock->sk;
		__netns_tracker_free(net, &sk->ns_tracker, false);
		sk->sk_net_refcnt = 1;
		get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
		sock_inuse_add(net, 1);
	} else {
	if (clcsock)
		smc->clcsock = clcsock;
	}

	else
		rc = smc_create_clcsk(net, sk, family);
out:
	return rc;
}
+5 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@
extern struct proto smc_proto;
extern struct proto smc_proto6;

/* smc sock initialization */
void smc_sk_init(struct net *net, struct sock *sk, int protocol);
/* clcsock initialization */
int smc_create_clcsk(struct net *net, struct sock *sk, int family);

#ifdef ATOMIC64_INIT
#define KERNEL_HAS_ATOMIC64
#endif