[PATCH net v2] can: netlink: fix static FD-NON-ISO mode validation

From: Zhu Ling

Date: Fri Sep 04 2026 - 12:39:44 EST


The static CAN_CTRLMODE_FD_NON_ISO mode does not have to be specified when
CAN FD is disabled. Since commit 6742ca18cb41 ("can: netlink: add userland
error messages"), ctrlstatic_missing is calculated before applying this
exception. Disabling CAN FD on a controller with static FD-NON-ISO mode
therefore fails with -EOPNOTSUPP.

Apply the exception to ctrlstatic_missing instead of modifying ctrlstatic.
Keep the original static mode mask and restore it after applying the
userspace mask, so a request that disables CAN FD cannot remove
CAN_CTRLMODE_FD_NON_ISO from priv->ctrlmode.

Fixes: 6742ca18cb41 ("can: netlink: add userland error messages")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Zhu Ling <zhuling0805@xxxxxx>
---
v2:
- Apply the FD-disabled exception to ctrlstatic_missing while keeping the
original static mode mask intact.
- Restore the static modes after applying the userspace mask so they cannot
be cleared from priv->ctrlmode.
v1: https://lore.kernel.org/all/tencent_B5154AEA68C02E81646C47664F2DCCB5AD0A@xxxxxx/

drivers/net/can/dev/netlink.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index 766d455950f5..1f67871020a5 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -332,7 +332,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,

/* do not check for static fd-non-iso if 'fd' is disabled */
if (!(maskedflags & CAN_CTRLMODE_FD))
- ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
+ ctrlstatic_missing &= ~CAN_CTRLMODE_FD_NON_ISO;

if (ctrlstatic_missing) {
NL_SET_ERR_MSG_FMT(extack,
@@ -357,9 +357,9 @@ static int can_ctrlmode_changelink(struct net_device *dev,
priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK |
CAN_CTRLMODE_XL_TMS);

- /* clear bits to be modified and copy the flag values */
+ /* clear bits to be modified, copy flags and restore static modes */
priv->ctrlmode &= ~cm->mask;
- priv->ctrlmode |= maskedflags;
+ priv->ctrlmode |= maskedflags | ctrlstatic;

/* Wipe potential leftovers from previous CAN FD/XL config */
if (!(priv->ctrlmode & CAN_CTRLMODE_FD)) {

base-commit: 641d03105cc0d2437e32fdeec164f91a4ccef6c4
--
2.43.0