From: Wei Zhang Date: Sat, 5 Apr 2014 23:17:35 +0000 (-0700) Subject: datapath: supply a dummy err_handler of gre_cisco_protocol to prevent kernel crash X-Git-Tag: sliver-openvswitch-2.2.90-1~5^2~14 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=43f31ef528f5e4b4751036ce2ef90ea1334bbe3f;p=sliver-openvswitch.git datapath: supply a dummy err_handler of gre_cisco_protocol to prevent kernel crash When use gre vport, openvswitch register a gre_cisco_protocol but does not supply a err_handler with it. The gre_cisco_err() in net/ipv4/gre_demux.c expect err_handler be provided with the gre_cisco_protocol implementation, and call ->err_handler() without existence check, cause the kernel crash. This patch provide a err_handler to fix this bug. Signed-off-by: Wei Zhang Signed-off-by: Jesse Gross --- diff --git a/datapath/linux/compat/include/net/gre.h b/datapath/linux/compat/include/net/gre.h index 6268655fc..dc035353d 100644 --- a/datapath/linux/compat/include/net/gre.h +++ b/datapath/linux/compat/include/net/gre.h @@ -17,6 +17,8 @@ struct gre_cisco_protocol { int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi); + int (*err_handler)(struct sk_buff *skb, u32 info, + const struct tnl_ptk_info *tpi); u8 priority; }; diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index 5ba5b8e44..5d5090c89 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -116,6 +116,25 @@ static int gre_rcv(struct sk_buff *skb, return PACKET_RCVD; } +/* Called with rcu_read_lock and BH disabled. */ +static int gre_err(struct sk_buff *skb, u32 info, + const struct tnl_ptk_info *tpi) +{ + struct ovs_net *ovs_net; + struct vport *vport; + + ovs_net = net_generic(dev_net(skb->dev), ovs_net_id); + if ((tpi->flags & TUNNEL_KEY) && (tpi->flags & TUNNEL_SEQ)) + vport = rcu_dereference(ovs_net->vport_net.gre64_vport); + else + vport = rcu_dereference(ovs_net->vport_net.gre_vport); + + if (unlikely(!vport)) + return PACKET_REJECT; + else + return PACKET_RCVD; +} + static int __send(struct vport *vport, struct sk_buff *skb, int tunnel_hlen, __be32 seq, __be16 gre64_flag) @@ -187,6 +206,7 @@ error: static struct gre_cisco_protocol gre_protocol = { .handler = gre_rcv, + .err_handler = gre_err, .priority = 1, };