* [PATCH net v2] macsec: check the resolved SCI for duplicates
@ 2026-10-01 20:40 Haseeb Malik via B4 Relay
2026-10-01 20:42 ` netdev-bot+sinfo
0 siblings, 1 reply; 2+ messages in thread
From: Haseeb Malik via B4 Relay @ 2026-10-01 20:40 UTC (permalink / raw)
To: Sabrina Dubroca, netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Shuah Khan, Hannes Frederic Sowa, linux-kselftest,
linux-kernel, Haseeb Malik
From: Haseeb Malik <haseebulhaq55@gmail.com>
An all-ones IFLA_MACSEC_SCI selects the default SCI derived from the
MACsec device's MAC address and port 1. macsec_init_secy() resolves this
value and stores the result in secy.sci, but macsec_newlink() checks for
duplicates using the unchanged local sci argument.
Consequently, an all-ones request can create a second MACsec device with
the same transmit SCI on the same lower device, while requesting that
SCI explicitly returns -EBUSY.
Resolve an undefined SCI in macsec_newlink() before initializing the
SecY, so initialization and duplicate detection use the same value.
Preserve the all-ones fallback when the resulting SCI is available.
Add regression tests for duplicate rejection using default, explicit and
all-ones SCI requests, and for valid fallback and reuse after deletion.
Skip these local tests when iproute2 lacks MACsec support.
Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Link: https://lists.openwall.net/netdev/2026/09/16/11
Assisted-by: LLM
Signed-off-by: Haseeb Malik <haseebulhaq55@gmail.com>
---
Changes in v2:
- Resolve undefined SCI in macsec_newlink(), as suggested by Sabrina.
- Check local iproute2 MACsec support in the new tests, as Sashiko noted.
Link to v1: https://lore.kernel.org/netdev/20260927-fix-macsec-duplicate-sci-v1-1-085bd742c8e9@gmail.com/
Tested on arm64/virtme with KASAN and lockdep: the new regression
tests go from 5 pass/2 fail to 7 pass/0 fail. The full MACsec selftest
passes all 15 cases without skips.
---
drivers/net/macsec.c | 8 ++--
tools/testing/selftests/drivers/net/macsec.py | 57 +++++++++++++++++++++++++--
2 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 78a19b134632..69686f22eda8 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -4143,9 +4143,6 @@ static void macsec_init_secy(struct net_device *dev, sci_t sci, u8 icv_len)
struct macsec_dev *macsec = macsec_priv(dev);
struct macsec_secy *secy = &macsec->secy;
- if (sci == MACSEC_UNDEF_SCI)
- sci = dev_to_sci(dev, MACSEC_PORT_ES);
-
secy->netdev = dev;
secy->operational = true;
secy->key_len = DEFAULT_SAK_LEN;
@@ -4178,7 +4175,7 @@ static int macsec_newlink(struct net_device *dev,
u8 icv_len = MACSEC_DEFAULT_ICV_LEN;
struct net_device *real_dev;
int err, mtu;
- sci_t sci;
+ sci_t sci = MACSEC_UNDEF_SCI;
if (!tb[IFLA_LINK])
return -EINVAL;
@@ -4231,7 +4228,8 @@ static int macsec_newlink(struct net_device *dev,
sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
else if (data && data[IFLA_MACSEC_PORT])
sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
- else
+
+ if (sci == MACSEC_UNDEF_SCI)
sci = dev_to_sci(dev, MACSEC_PORT_ES);
/* Registration can notify listeners before returning. */
diff --git a/tools/testing/selftests/drivers/net/macsec.py b/tools/testing/selftests/drivers/net/macsec.py
index 9a83d9542e04..81003bda9b0d 100755
--- a/tools/testing/selftests/drivers/net/macsec.py
+++ b/tools/testing/selftests/drivers/net/macsec.py
@@ -34,9 +34,10 @@ def _get_features(dev):
return ethtool(f"-k {dev}", json=True)[0]
-def _require_ip_macsec(cfg):
- """SKIP if iproute2 on local or remote lacks 'ip macsec' support."""
- for host in [None, cfg.remote]:
+def _require_ip_macsec(cfg=None):
+ """SKIP if iproute2 lacks MACsec locally or on cfg.remote, when given."""
+ hosts = [None, cfg.remote] if cfg is not None else [None]
+ for host in hosts:
out = cmd("ip macsec help", fail=False, host=host)
if "Usage" not in out.stdout + out.stderr:
where = "remote" if host else "local"
@@ -263,6 +264,54 @@ def test_offload_state(cfg) -> None:
"features should match first offload-on snapshot")
+@ksft_variants([
+ KsftNamedVariant("default", "", ""),
+ KsftNamedVariant("explicit", "", "sci {sci}"),
+ KsftNamedVariant("undefined", "", "sci ffffffffffffffff"),
+ KsftNamedVariant("undefined_default", "sci ffffffffffffffff", ""),
+ KsftNamedVariant("undefined_explicit", "sci ffffffffffffffff", "sci {sci}"),
+ KsftNamedVariant("undefined_twice", "sci ffffffffffffffff",
+ "sci ffffffffffffffff"),
+])
+def test_duplicate_sci(cfg, first, second) -> None:
+ """Reject duplicate transmit SCIs, including the undefined-SCI fallback."""
+
+ _require_ip_macsec()
+ ms0 = _macsec_name(0)
+ ms1 = _macsec_name(1)
+ sci = _get_mac(cfg.ifname).replace(":", "") + "0001"
+
+ ip(f"link add link {cfg.ifname} {ms0} type macsec {first}")
+ defer(ip, f"link del {ms0}")
+ with ksft_raises(CmdExitFailure):
+ ip(f"link add link {cfg.ifname} {ms1} type macsec "
+ f"{second.format(sci=sci)}")
+ # Clean up if the kernel incorrectly accepted the duplicate.
+ defer(ip, f"link del {ms1}")
+
+
+def test_undefined_sci(cfg) -> None:
+ """An undefined SCI still selects the default when it is available."""
+
+ _require_ip_macsec()
+ ms0 = _macsec_name(0)
+ ms1 = _macsec_name(1)
+ sci = _get_mac(cfg.ifname).replace(":", "") + "0001"
+
+ # A different port on the same lower device must not block the fallback.
+ ip(f"link add link {cfg.ifname} {ms0} type macsec port 2")
+ defer(ip, f"link del {ms0}")
+ ip(f"link add link {cfg.ifname} {ms1} type macsec sci ffffffffffffffff")
+ cleanup = defer(ip, f"link del {ms1}")
+ info = ip(f"-d link show dev {ms1}", json=True)[0]
+ ksft_eq(info["linkinfo"]["info_data"]["sci"], sci)
+
+ # Deleting a device must make its SCI available again.
+ cleanup.exec()
+ ip(f"link add link {cfg.ifname} {ms1} type macsec sci ffffffffffffffff")
+ defer(ip, f"link del {ms1}")
+
+
def _check_nsim_vid(cfg, vid, expected) -> None:
"""Checks if a VLAN is present. Only works on netdevsim."""
@@ -333,6 +382,8 @@ def main() -> None:
test_max_secy,
test_max_sc,
test_offload_state,
+ test_duplicate_sci,
+ test_undefined_sci,
test_vlan,
test_vlan_toggle,
], args=(cfg,))
---
base-commit: 11536ee3d3e0b1bd35b6f3f8df55a6053eb0c71d
change-id: 20260926-fix-macsec-duplicate-sci-ed7635ac1c35
Best regards,
--
Haseeb Malik <haseebulhaq55@gmail.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH net v2] macsec: check the resolved SCI for duplicates
2026-10-01 20:40 [PATCH net v2] macsec: check the resolved SCI for duplicates Haseeb Malik via B4 Relay
@ 2026-10-01 20:42 ` netdev-bot+sinfo
0 siblings, 0 replies; 2+ messages in thread
From: netdev-bot+sinfo @ 2026-10-01 20:42 UTC (permalink / raw)
To: Haseeb Malik
Cc: Sabrina Dubroca, netdev, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Shuah Khan,
Hannes Frederic Sowa, linux-kselftest, linux-kernel
Hi!
This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:
- How the issue was discovered, e.g. hit in production, hit during
development, syzbot report, manual code inspection, LLM or static
analysis tool scan.
Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.
The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-01 20:43 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01 20:40 [PATCH net v2] macsec: check the resolved SCI for duplicates Haseeb Malik via B4 Relay
2026-10-01 20:42 ` netdev-bot+sinfo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®