Message ID | 57f998406180ce626eca05d25f797216bf1713f5.1538493520.git.joseph.salisbury@canonical.com |
---|---|
State | New |
Headers | show |
Series | xfrm: Verify MAC header exists before overwriting eth_hdr(skb)->h_proto | expand |
On 11.10.2018 21:49, Joseph Salisbury wrote: > From: Yossi Kuperman <yossiku@mellanox.com> > > BugLink: https://bugs.launchpad.net/bugs/1795653 > > Artem Savkov reported that commit 5efec5c655dd leads to a packet loss under > IPSec configuration. It appears that his setup consists of a TUN device, > which does not have a MAC header. > > Make sure MAC header exists. > > Note: TUN device sets a MAC header pointer, although it does not have one. > > Fixes: 5efec5c655dd ("xfrm: Fix eth_hdr(skb)->h_proto to reflect inner IP version") > Reported-by: Artem Savkov <artem.savkov@gmail.com> > Tested-by: Artem Savkov <artem.savkov@gmail.com> > Signed-off-by: Yossi Kuperman <yossiku@mellanox.com> > Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> > (cherry picked from commit 87cdf3148b11d46382dbce2754ae7036aba96380) > Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- > net/ipv4/xfrm4_mode_tunnel.c | 3 ++- > net/ipv6/xfrm6_mode_tunnel.c | 3 ++- > 2 files changed, 4 insertions(+), 2 deletions(-) > > diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c > index 20ca486..acdde9d 100644 > --- a/net/ipv4/xfrm4_mode_tunnel.c > +++ b/net/ipv4/xfrm4_mode_tunnel.c > @@ -92,7 +92,8 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) > > skb_reset_network_header(skb); > skb_mac_header_rebuild(skb); > - eth_hdr(skb)->h_proto = skb->protocol; > + if (skb->mac_len) > + eth_hdr(skb)->h_proto = skb->protocol; > > err = 0; > > diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c > index dc93002..1ff2cff 100644 > --- a/net/ipv6/xfrm6_mode_tunnel.c > +++ b/net/ipv6/xfrm6_mode_tunnel.c > @@ -92,7 +92,8 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) > > skb_reset_network_header(skb); > skb_mac_header_rebuild(skb); > - eth_hdr(skb)->h_proto = skb->protocol; > + if (skb->mac_len) > + eth_hdr(skb)->h_proto = skb->protocol; > > err = 0; > >
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 20ca486..acdde9d 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -92,7 +92,8 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) skb_reset_network_header(skb); skb_mac_header_rebuild(skb); - eth_hdr(skb)->h_proto = skb->protocol; + if (skb->mac_len) + eth_hdr(skb)->h_proto = skb->protocol; err = 0; diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index dc93002..1ff2cff 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -92,7 +92,8 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) skb_reset_network_header(skb); skb_mac_header_rebuild(skb); - eth_hdr(skb)->h_proto = skb->protocol; + if (skb->mac_len) + eth_hdr(skb)->h_proto = skb->protocol; err = 0;