Thread (4 messages) flat view 4 messages, 3 authors, 1d ago
WARM1d

[PATCH net v3] net: loopback: ensure Ethernet header is linear before eth_type_trans

From: Ren Wei <hidden>
Date: 2026-07-28 15:04:22
Subsystem: networking drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

From: Wyatt Feng <redacted>

loopback_xmit() passes skbs to eth_type_trans(), which expects a
complete Ethernet header in linear data before consuming ETH_HLEN
bytes.

If an earlier path stripped or shortened the Ethernet header, a
non-linear skb can reach loopback with skb->len >= ETH_HLEN but fewer
than ETH_HLEN bytes in the linear area. eth_type_trans() then triggers
a BUG in __skb_pull(), causing a short-packet handling crash.

Check pskb_may_pull(skb, ETH_HLEN) before calling
eth_type_trans(). This also rejects packets whose total length is
shorter than ETH_HLEN. Account rejected packets as tx drops instead of
crashing.

The analogous VRF path is already protected because its IPv4 and IPv6
callers pull the Ethernet and network headers before calling
vrf_local_xmit().

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <redacted>
Closes: https://lore.kernel.org/r/40fe2d7dfce13411bfbe9271c0f7c54fb7e88e3b.1782548651.git.bronzed_45_vested@icloud.com (local)
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <redacted>
Signed-off-by: Ren Wei <redacted>
---
Changes since v2:
v2: https://lore.kernel.org/r/cover.1784709375.git.bronzed_45_vested@icloud.com (local)

- Moved the root-cause fix from the tc actions to loopback_xmit().
- Dropped the VRF change because both callers of vrf_local_xmit()
  already validate a full Ethernet and IP header.
- Left any additional act_vlan and act_skbmod hardening for a separate
  follow-up.

 drivers/net/loopback.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 1fb6ce6843ad..54b83a988f0b 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -72,6 +72,12 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
 {
 	int len;
 
+	if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) {
+		kfree_skb(skb);
+		dev_core_stats_tx_dropped_inc(dev);
+		return NETDEV_TX_OK;
+	}
+
 	skb_tx_timestamp(skb);
 
 	/* do not fool net_timestamp_check() with various clock bases */
-- 
2.47.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help