From: Wyatt Feng 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 Closes: https://lore.kernel.org/r/40fe2d7dfce13411bfbe9271c0f7c54fb7e88e3b.1782548651.git.bronzed_45_vested@icloud.com Assisted-by: Codex:GPT-5.4 Signed-off-by: Wyatt Feng Signed-off-by: Ren Wei --- Changes since v2: v2: https://lore.kernel.org/r/cover.1784709375.git.bronzed_45_vested@icloud.com - 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