summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2016-02-26 17:56:13 +0100
committerJiri Slaby <jslaby@suse.cz>2016-05-11 11:37:33 +0200
commitd469ee2137785282930819cce741e6543163d41b (patch)
tree7b401b683de7bbd5b567734e0a7ea648c836b388
parentcdfaba237820a99bad60d947530725151a611ca0 (diff)
downloadlinux-stable-d469ee2137785282930819cce741e6543163d41b.tar.gz
linux-stable-d469ee2137785282930819cce741e6543163d41b.tar.bz2
linux-stable-d469ee2137785282930819cce741e6543163d41b.zip
batman-adv: Check skb size before using encapsulated ETH+VLAN header
commit c78296665c3d81f040117432ab9e1cb125521b0c upstream. 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: Jiri Slaby <jslaby@suse.cz>
-rw-r--r--net/batman-adv/soft-interface.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 813db4e64602..40ac803135c6 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -326,10 +326,16 @@ void batadv_interface_rx(struct net_device *soft_iface,
skb_pull_rcsum(skb, hdr_size);
skb_reset_mac_header(skb);
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto dropped;
+
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;
vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
vid |= BATADV_VLAN_HAS_TAG;
@@ -343,8 +349,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()