From: xeb@mail.ru Date: Fri, 22 Jul 2011 20:49:40 +0000 (+0000) Subject: gre: fix improper error handling X-Git-Tag: v3.0.2~31 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=06e67267adf0e3b9a25a78250a1c7caefd36f843;p=karo-tx-linux.git gre: fix improper error handling [ Upstream commit 559fafb94ad9e4cd8774f39241917c57396f9fc5 ] Fix improper protocol err_handler, current implementation is fully unapplicable and may cause kernel crash due to double kfree_skb. Signed-off-by: Dmitry Kozlov Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index c6933f2ea310..3e3f75d96be5 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -97,27 +98,17 @@ drop: static void gre_err(struct sk_buff *skb, u32 info) { const struct gre_protocol *proto; - u8 ver; - - if (!pskb_may_pull(skb, 12)) - goto drop; + const struct iphdr *iph = (const struct iphdr *)skb->data; + u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; - ver = skb->data[1]&0x7f; if (ver >= GREPROTO_MAX) - goto drop; + return; rcu_read_lock(); proto = rcu_dereference(gre_proto[ver]); - if (!proto || !proto->err_handler) - goto drop_unlock; - proto->err_handler(skb, info); - rcu_read_unlock(); - return; - -drop_unlock: + if (proto && proto->err_handler) + proto->err_handler(skb, info); rcu_read_unlock(); -drop: - kfree_skb(skb); } static const struct net_protocol net_gre_protocol = {