ip_gre: validate csum_start only on pull
[linux-2.6-microblaze.git] / net / ipv4 / ip_gre.c
index 95419b7..0fe6c93 100644 (file)
@@ -473,8 +473,6 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
 
 static int gre_handle_offloads(struct sk_buff *skb, bool csum)
 {
-       if (csum && skb_checksum_start(skb) < skb->data)
-               return -EINVAL;
        return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
 }
 
@@ -632,15 +630,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
        }
 
        if (dev->header_ops) {
+               const int pull_len = tunnel->hlen + sizeof(struct iphdr);
+
                if (skb_cow_head(skb, 0))
                        goto free_skb;
 
                tnl_params = (const struct iphdr *)skb->data;
 
+               if (pull_len > skb_transport_offset(skb))
+                       goto free_skb;
+
                /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
                 * to gre header.
                 */
-               skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
+               skb_pull(skb, pull_len);
                skb_reset_mac_header(skb);
        } else {
                if (skb_cow_head(skb, dev->needed_headroom))
@@ -925,7 +928,7 @@ static const struct net_device_ops ipgre_netdev_ops = {
        .ndo_stop               = ipgre_close,
 #endif
        .ndo_start_xmit         = ipgre_xmit,
-       .ndo_do_ioctl           = ip_tunnel_ioctl,
+       .ndo_siocdevprivate     = ip_tunnel_siocdevprivate,
        .ndo_change_mtu         = ip_tunnel_change_mtu,
        .ndo_get_stats64        = dev_get_tstats64,
        .ndo_get_iflink         = ip_tunnel_get_iflink,