diff options
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 419960b0ba16..a0b6932c3afd 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1234,7 +1234,7 @@ static inline int | |||
1234 | ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | 1234 | ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
1235 | { | 1235 | { |
1236 | struct ip6_tnl *t = netdev_priv(dev); | 1236 | struct ip6_tnl *t = netdev_priv(dev); |
1237 | const struct iphdr *iph = ip_hdr(skb); | 1237 | const struct iphdr *iph; |
1238 | int encap_limit = -1; | 1238 | int encap_limit = -1; |
1239 | struct flowi6 fl6; | 1239 | struct flowi6 fl6; |
1240 | __u8 dsfield; | 1240 | __u8 dsfield; |
@@ -1242,6 +1242,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1242 | u8 tproto; | 1242 | u8 tproto; |
1243 | int err; | 1243 | int err; |
1244 | 1244 | ||
1245 | /* ensure we can access the full inner ip header */ | ||
1246 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
1247 | return -1; | ||
1248 | |||
1249 | iph = ip_hdr(skb); | ||
1245 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 1250 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
1246 | 1251 | ||
1247 | tproto = READ_ONCE(t->parms.proto); | 1252 | tproto = READ_ONCE(t->parms.proto); |
@@ -1306,7 +1311,7 @@ static inline int | |||
1306 | ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | 1311 | ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
1307 | { | 1312 | { |
1308 | struct ip6_tnl *t = netdev_priv(dev); | 1313 | struct ip6_tnl *t = netdev_priv(dev); |
1309 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); | 1314 | struct ipv6hdr *ipv6h; |
1310 | int encap_limit = -1; | 1315 | int encap_limit = -1; |
1311 | __u16 offset; | 1316 | __u16 offset; |
1312 | struct flowi6 fl6; | 1317 | struct flowi6 fl6; |
@@ -1315,6 +1320,10 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1315 | u8 tproto; | 1320 | u8 tproto; |
1316 | int err; | 1321 | int err; |
1317 | 1322 | ||
1323 | if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) | ||
1324 | return -1; | ||
1325 | |||
1326 | ipv6h = ipv6_hdr(skb); | ||
1318 | tproto = READ_ONCE(t->parms.proto); | 1327 | tproto = READ_ONCE(t->parms.proto); |
1319 | if ((tproto != IPPROTO_IPV6 && tproto != 0) || | 1328 | if ((tproto != IPPROTO_IPV6 && tproto != 0) || |
1320 | ip6_tnl_addr_conflict(t, ipv6h)) | 1329 | ip6_tnl_addr_conflict(t, ipv6h)) |