mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 07:32:29 +02:00
ip_tunnel: fix kernel panic with icmp_dest_unreach
[ Upstream commit a622260254 ]
Daniel Petre reported crashes in icmp_dst_unreach() with following call
graph:
Daniel found a similar problem mentioned in
http://lkml.indiana.edu/hypermail/linux/kernel/1007.0/00961.html
And indeed this is the root cause : skb->cb[] contains data fooling IP
stack.
We must clear IPCB in ip_tunnel_xmit() sooner in case dst_link_failure()
is called. Or else skb->cb[] might contain garbage from GSO segmentation
layer.
A similar fix was tested on linux-3.9, but gre code was refactored in
linux-3.10. I'll send patches for stable kernels as well.
Many thanks to Daniel for providing reports, patches and testing !
Reported-by: Daniel Petre <daniel.petre@rcs-rds.ro>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fa17eb7500
commit
3c353df4ca
|
|
@ -722,6 +722,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
|||
tiph = &tunnel->parms.iph;
|
||||
}
|
||||
|
||||
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
||||
if ((dst = tiph->daddr) == 0) {
|
||||
/* NBMA tunnel */
|
||||
|
||||
|
|
@ -865,7 +866,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
|||
skb_reset_transport_header(skb);
|
||||
skb_push(skb, gre_hlen);
|
||||
skb_reset_network_header(skb);
|
||||
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
||||
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
|
||||
IPSKB_REROUTED);
|
||||
skb_dst_drop(skb);
|
||||
|
|
|
|||
|
|
@ -448,6 +448,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (tos & 1)
|
||||
tos = old_iph->tos;
|
||||
|
||||
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
||||
if (!dst) {
|
||||
/* NBMA tunnel */
|
||||
if ((rt = skb_rtable(skb)) == NULL) {
|
||||
|
|
@ -530,7 +531,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
skb->transport_header = skb->network_header;
|
||||
skb_push(skb, sizeof(struct iphdr));
|
||||
skb_reset_network_header(skb);
|
||||
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
||||
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
|
||||
IPSKB_REROUTED);
|
||||
skb_dst_drop(skb);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user