VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45940

CVE-2026-45940

Description

In the Linux kernel, the following vulnerability has been resolved:

net: stmmac: fix oops when split header is enabled

For GMAC4, when split header is enabled, in some rare cases, the hardware does not fill buf2 of the first descriptor with payload. Thus we cannot assume buf2 is always fully filled if it is not the last descriptor. Otherwise, the length of buf2 of the second descriptor will be calculated wrong and cause an oops:

Unable to handle kernel paging request at virtual address ffff00019246bfc0 ... x2 : 0000000000000040 x1 : ffff00019246bfc0 x0 : ffff00009246c000 Call trace: dcache_inval_poc+0x28/0x58 (P) dma_direct_sync_single_for_cpu+0x38/0x6c __dma_sync_single_for_cpu+0x34/0x6c stmmac_napi_poll_rx+0x8f0/0xb60 __napi_poll.constprop.0+0x30/0x144 net_rx_action+0x160/0x274 handle_softirqs+0x1b8/0x1fc ...

To fix this, the PL bit-field in RDES3 register is used for all descriptors, whether it is the last descriptor or not.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In the Linux kernel's stmmac driver for GMAC4, enabling split header can cause an oops due to incorrect buffer length calculation when hardware fails to fill buf2.

Vulnerability

In the Linux kernel's stmmac driver for GMAC4, when split header is enabled, a rare hardware condition causes the first descriptor's buf2 to not be filled with payload. The driver incorrectly assumes buf2 is fully filled for non-last descriptors, leading to an incorrect length calculation for the second descriptor's buf2. This results in a kernel oops due to an invalid memory access. The vulnerability affects versions with split header support enabled.

Exploitation

An attacker would need to trigger the specific hardware condition where the GMAC4 controller does not fill buf2 of the first descriptor. This likely requires network traffic that causes the split header feature to be used. No special privileges are needed beyond network access. The oops occurs during RX packet processing in stmmac_napi_poll_rx, leading to a denial of service.

Impact

Successful exploitation causes a kernel oops, resulting in a system crash or denial of service. The oops trace shows an invalid memory access in dcache_inval_poc during DMA synchronization. No privilege escalation or data disclosure is indicated.

Mitigation

The fix is included in the Linux kernel stable commit [1]. Users should update to a kernel version containing commit 36f81cb7d82e9614a7058da6abdf2e3a03993df1. The fix uses the PL bit-field in the RDES3 register for all descriptors to correctly determine buffer length. No workaround is mentioned; updating the kernel is recommended.

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

1

Patches

6
b1f23df09e7d

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index a38976c65149c4..46299b7925b44a 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -4880,13 +4880,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
36f81cb7d82e

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index a379221b96a348..f98fd254315f6d 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -5023,13 +5023,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph_active)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
babab1b42ed6

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index c63099a77cc0c4..82375d34ad57d6 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -5040,13 +5040,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph_active)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
36f81cb7d82e

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index a379221b96a348..f98fd254315f6d 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -5023,13 +5023,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph_active)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
b1f23df09e7d

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index a38976c65149c4..46299b7925b44a 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -4880,13 +4880,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
babab1b42ed6

net: stmmac: fix oops when split header is enabled

1 file changed · +17 4
  • drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17 4 modified
    diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    index c63099a77cc0c4..82375d34ad57d6 100644
    --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    @@ -5040,13 +5040,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
     	if (!priv->sph_active)
     		return 0;
     
    -	/* Not last descriptor */
    -	if (status & rx_not_ls)
    +	/* For GMAC4, when split header is enabled, in some rare cases, the
    +	 * hardware does not fill buf2 of the first descriptor with payload.
    +	 * Thus we cannot assume buf2 is always fully filled if it is not
    +	 * the last descriptor. Otherwise, the length of buf2 of the second
    +	 * descriptor will be calculated wrong and cause an oops.
    +	 *
    +	 * If this is the last descriptor, 'plen' is the length of the
    +	 * received packet that was transferred to system memory.
    +	 * Otherwise, it is the accumulated number of bytes that have been
    +	 * transferred for the current packet.
    +	 *
    +	 * Thus 'plen - len' always gives the correct length of buf2.
    +	 */
    +
    +	/* Not GMAC4 and not last descriptor */
    +	if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
     		return priv->dma_conf.dma_buf_sz;
     
    +	/* GMAC4 or last descriptor */
     	plen = stmmac_get_rx_frame_len(priv, p, coe);
     
    -	/* Last descriptor */
     	return plen - len;
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect buf2 length calculation in stmmac_rx_buf2_len() for GMAC4 with split header enabled: the code assumed a non-last descriptor's buf2 was always fully filled (dma_buf_sz), but GMAC4 hardware may not fill buf2 on the first descriptor, causing an oversized length that leads to an out-of-bounds memory access."

Attack vector

An attacker can trigger this bug by sending network packets to a system using the stmmac driver with a GMAC4 core and split header (SPH) enabled. When the GMAC4 hardware processes a multi-descriptor packet and, in rare cases, does not fill buf2 of the first descriptor, the function stmmac_rx_buf2_len() returns the full dma_buf_sz for that descriptor instead of the actual payload length. This causes the subsequent descriptor's buf2 length to be calculated incorrectly, leading to a kernel page fault when the NAPI poll routine (stmmac_napi_poll_rx) attempts to sync the DMA buffer for CPU access [patch_id=2661161].

Affected code

The vulnerable function is stmmac_rx_buf2_len() in drivers/net/ethernet/stmicro/stmmac/stmmac_main.c [patch_id=2661161]. The logic that incorrectly returned priv->dma_conf.dma_buf_sz for any non-last descriptor when split header is enabled is the root cause.

What the fix does

The patch modifies stmmac_rx_buf2_len() in drivers/net/ethernet/stmicro/stmmac/stmmac_main.c to change the condition that returns dma_buf_sz. Previously, any non-last descriptor (status & rx_not_ls) returned the full buffer size. Now, that shortcut is only taken for non-GMAC4 cores; for GMAC4 (or the last descriptor), the code falls through to compute plen via stmmac_get_rx_frame_len() and returns plen - len. This uses the PL bit-field from the RDES3 register, which always reflects the actual transferred byte count, regardless of whether the descriptor is the last one. This closes the vulnerability by never assuming buf2 is fully filled on GMAC4 [patch_id=2661161].

Preconditions

  • configThe system must use a GMAC4 Ethernet core (DWMAC_CORE_GMAC4)
  • configSplit header (SPH) must be enabled on the stmmac device
  • networkAn attacker must be able to send network packets to the affected interface

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.