[Devel] [PATCH RHEL7 COMMIT] venet: ipX_forward headroom check
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Jul 17 17:57:19 MSK 2017
Please consider to prepare a ReadyKernel patch for it.
https://readykernel.com/
--
Best regards,
Konstantin Khorenko,
Virtuozzo Linux Kernel Team
On 07/17/2017 05:56 PM, Konstantin Khorenko wrote:
> The commit is pushed to "branch-rh7-3.10.0-514.26.1.vz7.33.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
> after rh7-3.10.0-514.26.1.vz7.33.8
> ------>
> commit 9a05b36b74f00f920b750511e6fbf87a3d6e9324
> Author: Vasily Averin <vvs at virtuozzo.com>
> Date: Mon Jul 17 18:56:13 2017 +0400
>
> venet: ipX_forward headroom check
>
> 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>
> ---
> net/ipv4/ip_forward.c | 10 ++++++----
> net/ipv6/ip6_output.c | 8 +++++---
> 2 files changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
> index 17bbdd8..556792c 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 has 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 11e64fb..d569fa5 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 has 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