batman-adv: Check skb size before using encapsulated ETH+VLAN header
authorSven Eckelmann <sven@narfation.org>
Fri, 26 Feb 2016 16:56:13 +0000 (17:56 +0100)
committerSasha Levin <sasha.levin@oracle.com>
Tue, 12 Jul 2016 12:48:05 +0000 (08:48 -0400)
[ Upstream commit c78296665c3d81f040117432ab9e1cb125521b0c ]

The encapsulated ethernet and VLAN header may be outside the received
ethernet frame. Thus the skb buffer size has to be checked before it can be
parsed to find out if it encapsulates another batman-adv packet.

Fixes: 420193573f11 ("batman-adv: softif bridge loop avoidance")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
net/batman-adv/soft-interface.c

index 492b0593dc2ff7030d572334011f6c04cc1da6c6..0bb7cae486b3f6323b126c566b5627f4c49e86dd 100644 (file)
@@ -378,11 +378,17 @@ void batadv_interface_rx(struct net_device *soft_iface,
         */
        nf_reset(skb);
 
+       if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+               goto dropped;
+
        vid = batadv_get_vid(skb, 0);
        ethhdr = eth_hdr(skb);
 
        switch (ntohs(ethhdr->h_proto)) {
        case ETH_P_8021Q:
+               if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
+                       goto dropped;
+
                vhdr = (struct vlan_ethhdr *)skb->data;
 
                if (vhdr->h_vlan_encapsulated_proto != ethertype)
@@ -394,8 +400,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
        }
 
        /* skb->dev & skb->pkt_type are set here */
-       if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
-               goto dropped;
        skb->protocol = eth_type_trans(skb, soft_iface);
 
        /* should not be necessary anymore as we use skb_pull_rcsum()