[Devel] [patch vz7] venet: ipX_forward headroom check
Vasily Averin
vvs at virtuozzo.com
Fri Jul 14 13:12:07 MSK 2017
skb from virtual (NETIF_F_VENET) devices do not call skb_cow() in ip[6]_forward.
As result such skb can lack space for eth header, it can trigger skb_under_panic
and crash the host.
https://jira.sw.ru/browse/PSBM-68362
Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
-------------- next part --------------
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 17bbdd8..bd34dc31 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -75,6 +75,7 @@ int ip_forward(struct sk_buff *skb)
struct iphdr *iph; /* Our header */
struct rtable *rt; /* Route we use */
struct ip_options *opt = &(IPCB(skb)->opt);
+ unsigned int hroom;
if (skb_warn_if_lro(skb))
goto drop;
@@ -125,16 +126,17 @@ int ip_forward(struct sk_buff *skb)
* in pkts path with mandatory ttl decr, that is
* sufficient to prevent routing loops.
*/
- iph = ip_hdr(skb);
+ hroom = LL_RESERVED_SPACE(rt->dst.dev)+rt->dst.header_len;
if (
-#ifdef CONFIG_IP_ROUTE_NAT
+#ifdef CONFIG_IP_ROUTE_NAT
(rt->rt_flags & RTCF_NAT) == 0 && /* no NAT mangling expected */
#endif /* and */
- (skb->dev->features & NETIF_F_VENET)) /* src is VENET device */
+ (skb->dev->features & NETIF_F_VENET) && /* src is VENET device and */
+ (skb_headroom(skb) >= hroom)) /* skb have enough headroom */
goto no_ttl_decr;
/* We are about to mangle packet. Copy it! */
- if (skb_cow(skb, LL_RESERVED_SPACE(rt->dst.dev)+rt->dst.header_len))
+ if (skb_cow(skb, hroom))
goto drop;
iph = ip_hdr(skb);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index dc632eb..0e6ad0f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -346,6 +346,7 @@ int ip6_forward(struct sk_buff *skb)
struct ipv6hdr *hdr = ipv6_hdr(skb);
struct inet6_skb_parm *opt = IP6CB(skb);
struct net *net = dev_net(dst->dev);
+ unsigned int hroom;
u32 mtu;
if (net->ipv6.devconf_all->forwarding == 0)
@@ -487,11 +488,12 @@ int ip6_forward(struct sk_buff *skb)
* in pkts path with mandatory ttl decr, that is
* sufficient to prevent routing loops.
*/
- hdr = ipv6_hdr(skb);
- if (skb->dev->features & NETIF_F_VENET) /* src is VENET device */
+ hroom = dst->dev->hard_header_len;
+ if ((skb->dev->features & NETIF_F_VENET) && /* src is VENET device */
+ (skb_headroom(skb) >= hroom)) /* and skb have enough headroom */
goto no_ttl_decr;
- if (skb_cow(skb, dst->dev->hard_header_len)) {
+ if (skb_cow(skb, hroom)) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
goto drop;
}
More information about the Devel
mailing list