lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251031031828.111364-1-alibuda@linux.alibaba.com>
Date: Fri, 31 Oct 2025 11:18:28 +0800
From: "D. Wythe" <alibuda@...ux.alibaba.com>
To: mjambigi@...ux.ibm.com,
	wenjia@...ux.ibm.com,
	wintera@...ux.ibm.com,
	dust.li@...ux.alibaba.com,
	tonylu@...ux.alibaba.com,
	guwen@...ux.alibaba.com
Cc: kuba@...nel.org,
	davem@...emloft.net,
	netdev@...r.kernel.org,
	linux-s390@...r.kernel.org,
	linux-rdma@...r.kernel.org,
	pabeni@...hat.com,
	edumazet@...gle.com,
	sidraya@...ux.ibm.com,
	jaka@...ux.ibm.com
Subject: [PATCH net] net/smc: fix mismatch between CLC header and proposal extensions

The current CLC proposal message construction uses a mix of
`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
to include optional extensions (IPv6 prefix extension for v1, and v2
extension). This leads to a critical inconsistency: when
`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
only link-local addresses, or when the local IP address and the outgoing
interface’s network address are not in the same subnet.

As a result, the proposal message is assembled using the stale
`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
included even though the header indicates v1 is not supported.
The peer then receives a malformed CLC proposal where the header type
does not match the payload, and immediately resets the connection.

Fix this by consistently using `pclc_base->hdr.typev1` and
`pclc_base->hdr.typev2`—the authoritative fields that reflect the
actual capabilities advertised in the CLC header—when deciding whether
to include optional extensions, as required by the SMC-R v2
specification ("V1 IP Subnet Extension and V2 Extension only present if
applicable").

Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
Signed-off-by: D. Wythe <alibuda@...ux.alibaba.com>
---
 net/smc/smc_clc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 157aace169d4..d9ff5f433720 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -922,7 +922,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 				htons(smc_ism_get_chid(ini->ism_dev[0]));
 		}
 	}
-	if (ini->smc_type_v2 == SMC_TYPE_N) {
+	if (pclc_base->hdr.typev2 == SMC_TYPE_N) {
 		pclc_smcd->v2_ext_offset = 0;
 	} else {
 		struct smc_clc_eid_entry *ueident;
@@ -931,7 +931,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		v2_ext->hdr.flag.release = SMC_RELEASE;
 		v2_ext_offset = sizeof(*pclc_smcd) -
 			offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
-		if (ini->smc_type_v1 != SMC_TYPE_N)
+		if (pclc_base->hdr.typev1 != SMC_TYPE_N)
 			v2_ext_offset += sizeof(*pclc_prfx) +
 						pclc_prfx->ipv6_prefixes_cnt *
 						sizeof(ipv6_prfx[0]);
@@ -949,7 +949,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		}
 		read_unlock(&smc_clc_eid_table.lock);
 	}
-	if (smcd_indicated(ini->smc_type_v2)) {
+	if (smcd_indicated(pclc_base->hdr.typev2)) {
 		struct smcd_gid smcd_gid;
 		u8 *eid = NULL;
 		int entry = 0;
@@ -987,7 +987,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		}
 		v2_ext->hdr.ism_gid_cnt = entry;
 	}
-	if (smcr_indicated(ini->smc_type_v2)) {
+	if (smcr_indicated(pclc_base->hdr.typev2)) {
 		memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
 		v2_ext->max_conns = net->smc.sysctl_max_conns_per_lgr;
 		v2_ext->max_links = net->smc.sysctl_max_links_per_lgr;
@@ -1003,7 +1003,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 	vec[i++].iov_len = sizeof(*pclc_base);
 	vec[i].iov_base = pclc_smcd;
 	vec[i++].iov_len = sizeof(*pclc_smcd);
-	if (ini->smc_type_v1 != SMC_TYPE_N) {
+	if (pclc_base->hdr.typev1 != SMC_TYPE_N) {
 		vec[i].iov_base = pclc_prfx;
 		vec[i++].iov_len = sizeof(*pclc_prfx);
 		if (pclc_prfx->ipv6_prefixes_cnt > 0) {
@@ -1012,11 +1012,11 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 					   sizeof(ipv6_prfx[0]);
 		}
 	}
-	if (ini->smc_type_v2 != SMC_TYPE_N) {
+	if (pclc_base->hdr.typev2 != SMC_TYPE_N) {
 		vec[i].iov_base = v2_ext;
 		vec[i++].iov_len = sizeof(*v2_ext) +
 				   (v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
-		if (smcd_indicated(ini->smc_type_v2)) {
+		if (smcd_indicated(pclc_base->hdr.typev2)) {
 			vec[i].iov_base = smcd_v2_ext;
 			vec[i++].iov_len = sizeof(*smcd_v2_ext);
 			if (ini->ism_offered_cnt) {
-- 
2.45.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ