|
Thomas Bogendoerfer |
132b98 |
From: Guillaume Nault <gnault@redhat.com>
|
|
Thomas Bogendoerfer |
132b98 |
Date: Wed, 6 Apr 2022 16:18:54 +0200
|
|
Thomas Bogendoerfer |
132b98 |
Subject: veth: Ensure eth header is in skb's linear part
|
|
Thomas Bogendoerfer |
132b98 |
Patch-mainline: v5.18-rc3
|
|
Thomas Bogendoerfer |
132b98 |
Git-commit: 726e2c5929de841fdcef4e2bf995680688ae1b87
|
|
Thomas Bogendoerfer |
132b98 |
References: git-fixes
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
After feeding a decapsulated packet to a veth device with act_mirred,
|
|
Thomas Bogendoerfer |
132b98 |
skb_headlen() may be 0. But veth_xmit() calls __dev_forward_skb(),
|
|
Thomas Bogendoerfer |
132b98 |
which expects at least ETH_HLEN byte of linear data (as
|
|
Thomas Bogendoerfer |
132b98 |
__dev_forward_skb2() calls eth_type_trans(), which pulls ETH_HLEN bytes
|
|
Thomas Bogendoerfer |
132b98 |
unconditionally).
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
Use pskb_may_pull() to ensure veth_xmit() respects this constraint.
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
kernel BUG at include/linux/skbuff.h:2328!
|
|
Thomas Bogendoerfer |
132b98 |
RIP: 0010:eth_type_trans+0xcf/0x140
|
|
Thomas Bogendoerfer |
132b98 |
Call Trace:
|
|
Thomas Bogendoerfer |
132b98 |
<IRQ>
|
|
Thomas Bogendoerfer |
132b98 |
__dev_forward_skb2+0xe3/0x160
|
|
Thomas Bogendoerfer |
132b98 |
veth_xmit+0x6e/0x250 [veth]
|
|
Thomas Bogendoerfer |
132b98 |
dev_hard_start_xmit+0xc7/0x200
|
|
Thomas Bogendoerfer |
132b98 |
__dev_queue_xmit+0x47f/0x520
|
|
Thomas Bogendoerfer |
132b98 |
? skb_ensure_writable+0x85/0xa0
|
|
Thomas Bogendoerfer |
132b98 |
? skb_mpls_pop+0x98/0x1c0
|
|
Thomas Bogendoerfer |
132b98 |
tcf_mirred_act+0x442/0x47e [act_mirred]
|
|
Thomas Bogendoerfer |
132b98 |
tcf_action_exec+0x86/0x140
|
|
Thomas Bogendoerfer |
132b98 |
fl_classify+0x1d8/0x1e0 [cls_flower]
|
|
Thomas Bogendoerfer |
132b98 |
? dma_pte_clear_level+0x129/0x1a0
|
|
Thomas Bogendoerfer |
132b98 |
? dma_pte_clear_level+0x129/0x1a0
|
|
Thomas Bogendoerfer |
132b98 |
? prb_fill_curr_block+0x2f/0xc0
|
|
Thomas Bogendoerfer |
132b98 |
? skb_copy_bits+0x11a/0x220
|
|
Thomas Bogendoerfer |
132b98 |
__tcf_classify+0x58/0x110
|
|
Thomas Bogendoerfer |
132b98 |
tcf_classify_ingress+0x6b/0x140
|
|
Thomas Bogendoerfer |
132b98 |
__netif_receive_skb_core.constprop.0+0x47d/0xfd0
|
|
Thomas Bogendoerfer |
132b98 |
? __iommu_dma_unmap_swiotlb+0x44/0x90
|
|
Thomas Bogendoerfer |
132b98 |
__netif_receive_skb_one_core+0x3d/0xa0
|
|
Thomas Bogendoerfer |
132b98 |
netif_receive_skb+0x116/0x170
|
|
Thomas Bogendoerfer |
132b98 |
be_process_rx+0x22f/0x330 [be2net]
|
|
Thomas Bogendoerfer |
132b98 |
be_poll+0x13c/0x370 [be2net]
|
|
Thomas Bogendoerfer |
132b98 |
__napi_poll+0x2a/0x170
|
|
Thomas Bogendoerfer |
132b98 |
net_rx_action+0x22f/0x2f0
|
|
Thomas Bogendoerfer |
132b98 |
__do_softirq+0xca/0x2a8
|
|
Thomas Bogendoerfer |
132b98 |
__irq_exit_rcu+0xc1/0xe0
|
|
Thomas Bogendoerfer |
132b98 |
common_interrupt+0x83/0xa0
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
Fixes: e314dbdc1c0d ("[NET]: Virtual ethernet device driver.")
|
|
Thomas Bogendoerfer |
132b98 |
Signed-off-by: Guillaume Nault <gnault@redhat.com>
|
|
Thomas Bogendoerfer |
132b98 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Thomas Bogendoerfer |
132b98 |
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
|
|
Thomas Bogendoerfer |
132b98 |
---
|
|
Thomas Bogendoerfer |
132b98 |
drivers/net/veth.c | 2 +-
|
|
Thomas Bogendoerfer |
132b98 |
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
--- a/drivers/net/veth.c
|
|
Thomas Bogendoerfer |
132b98 |
+++ b/drivers/net/veth.c
|
|
Thomas Bogendoerfer |
132b98 |
@@ -325,7 +325,7 @@ static netdev_tx_t veth_xmit(struct sk_b
|
|
Thomas Bogendoerfer |
132b98 |
|
|
Thomas Bogendoerfer |
132b98 |
rcu_read_lock();
|
|
Thomas Bogendoerfer |
132b98 |
rcv = rcu_dereference(priv->peer);
|
|
Thomas Bogendoerfer |
132b98 |
- if (unlikely(!rcv)) {
|
|
Thomas Bogendoerfer |
132b98 |
+ if (unlikely(!rcv) || !pskb_may_pull(skb, ETH_HLEN)) {
|
|
Thomas Bogendoerfer |
132b98 |
kfree_skb(skb);
|
|
Thomas Bogendoerfer |
132b98 |
goto drop;
|
|
Thomas Bogendoerfer |
132b98 |
}
|