]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net/smc: fix mismatch between CLC header and proposal
authorD. Wythe <alibuda@linux.alibaba.com>
Fri, 7 Nov 2025 02:40:29 +0000 (10:40 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Nov 2025 09:35:50 +0000 (10:35 +0100)
[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]

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.

The fix ensures consistency between the CLC header flags and the actual
payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
when prefix setup fails.

Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/smc/smc_clc.c

index 8a794333e9927c8b8f2884b068241f48c804d328..b3a8053d4ab4b1f4f04f2c36adc340b7843f27e2 100644 (file)
@@ -887,6 +887,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
                                return SMC_CLC_DECL_CNFERR;
                        }
                        pclc_base->hdr.typev1 = SMC_TYPE_N;
+                       ini->smc_type_v1 = SMC_TYPE_N;
                } else {
                        pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
                        plen += sizeof(*pclc_prfx) +