CVE-2026-45849
Description
In the Linux kernel, the following vulnerability has been resolved:
net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
ocelot_port_xmit_inj() calls ocelot_can_inject() and ocelot_port_inject_frame() without holding the injection group lock. Both functions contain lockdep_assert_held() for the injection lock, and the correct caller felix_port_deferred_xmit() properly acquires the lock using ocelot_lock_inj_grp() before calling these functions.
Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register injection path to fix the missing lock protection. The FDMA path is not affected as it uses its own locking mechanism.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing lock protection in ocelot_port_xmit_inj() can cause race conditions; fixed in Linux kernel commit 0b217a40156f.
Vulnerability
In the Linux kernel's net: mscc: ocelot driver, the function ocelot_port_xmit_inj() calls ocelot_can_inject() and ocelot_port_inject_frame() without holding the injection group lock. This affects the register injection path. The FDMA path is not vulnerable as it uses its own locking. The issue was introduced in a prior version and persists until the fix commit [1].
Exploitation
An attacker with local access to the system may trigger a race condition by concurrently exploiting the missing lock. The attack requires precise timing and the ability to invoke ocelot_port_xmit_inj() on a vulnerable kernel.
Impact
Successful exploitation could lead to a denial of service, system instability, or potentially information disclosure due to race conditions. Privilege escalation cannot be ruled out, though no specific exploit details are provided.
Mitigation
The fix is contained in Linux kernel stable commit 0b217a40156f [1]. System administrators should update their kernel to version including this commit or later. No workarounds are documented.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
127ac58d883280net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
1 file changed · +10 −3
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index df863657c87de5..7df78004dba91f 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
51c32ae7fae1net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
1 file changed · +10 −3
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
63da961381e0net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
1 file changed · +10 −3
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
026f6513c588net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
1 file changed · +10 −3
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
0b217a40156fnet: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 14de948f72464a..e4f4ea97c55b71 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 14de948f72464a..e4f4ea97c55b71 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
cc1b179f778fnet: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 84b3dcf1d2f5a8..b516b4e1ed974b 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 84b3dcf1d2f5a8..b516b4e1ed974b 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
0b217a40156fnet: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 14de948f72464a..e4f4ea97c55b71 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 14de948f72464a..e4f4ea97c55b71 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
51c32ae7fae1net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
63da961381e0net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
cc1b179f778fnet: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 84b3dcf1d2f5a8..b516b4e1ed974b 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 84b3dcf1d2f5a8..b516b4e1ed974b 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
7ac58d883280net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index df863657c87de5..7df78004dba91f 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index df863657c87de5..7df78004dba91f 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
026f6513c588net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
2 files changed · +20 −6
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
drivers/net/ethernet/mscc/ocelot_net.c+10 −3 modifieddiff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index a7966c174b2e22..1b82693204640d 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, int port = priv->port.index; u32 rew_op = 0; - if (!ocelot_can_inject(ocelot, 0)) + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_BUSY; + } - if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); return NETDEV_TX_OK; + } ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ocelot_unlock_inj_grp(ocelot, 0); + consume_skb(skb); return NETDEV_TX_OK; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing lock acquisition in ocelot_port_xmit_inj() before calling ocelot_can_inject() and ocelot_port_inject_frame(), which both assert the injection group lock is held."
Attack vector
An attacker who can trigger the register-based injection path (as opposed to the FDMA path) in the Ocelot switch driver can cause concurrent access to the injection group hardware registers without proper locking [patch_id=2662121]. This can lead to corrupted frame injection state or undefined hardware behavior. The attack is triggered by sending network packets that cause the kernel to call `ocelot_port_xmit_inj()` from a context that does not hold the injection group lock, bypassing the lockdep assertion present in the helper functions.
Affected code
The vulnerability is in `drivers/net/ethernet/mscc/ocelot_net.c` in the function `ocelot_port_xmit_inj()`. This function calls `ocelot_can_inject()` and `ocelot_port_inject_frame()` without first acquiring the injection group lock via `ocelot_lock_inj_grp()` [patch_id=2662121]. The correct caller `felix_port_deferred_xmit()` properly holds the lock before calling these functions, but `ocelot_port_xmit_inj()` itself was missing the lock acquisition.
What the fix does
The patch adds `ocelot_lock_inj_grp(ocelot, 0)` at the beginning of `ocelot_port_xmit_inj()` and `ocelot_unlock_inj_grp(ocelot, 0)` after the frame injection completes [patch_id=2662121]. It also adds unlock calls on the two early-return paths (when `ocelot_can_inject()` returns false and when `ocelot_xmit_timestamp()` returns false) to ensure the lock is released in all code paths. This ensures the injection group lock is held for the entire duration of the register injection sequence, satisfying the `lockdep_assert_held()` assertions inside `ocelot_can_inject()` and `ocelot_port_inject_frame()`.
Preconditions
- configThe system must use the Ocelot switch driver with register-based injection (not FDMA).
- inputAn attacker must be able to trigger the ocelot_port_xmit_inj() code path, typically by sending network packets through the affected interface.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- git.kernel.org/stable/c/026f6513c5880c2c89e38ad66bbec2868f978605nvd
- git.kernel.org/stable/c/0b217a40156f497e09dd20d3f7baec40c785f386nvd
- git.kernel.org/stable/c/51c32ae7fae14552d79f7139614b77c1bbd57a48nvd
- git.kernel.org/stable/c/63da961381e0d979459dede713001f8452364477nvd
- git.kernel.org/stable/c/7ac58d8832802ec89baa7539e13e6d58a88cce04nvd
- git.kernel.org/stable/c/cc1b179f778f98270bdbbb48d183b4b6427ae198nvd
News mentions
0No linked articles in our index yet.