lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 28 May 2020 13:34:45 -0700
From:   Petar Penkov <ppenkov.kernel@...il.com>
To:     Willem de Bruijn <willemdebruijn.kernel@...il.com>
Cc:     Networking <netdev@...r.kernel.org>,
        "David S. Miller" <davem@...emloft.net>,
        Willem de Bruijn <willemb@...gle.com>
Subject: Re: [PATCH net] tun: correct header offsets in napi frags mode

On Thu, May 28, 2020 at 10:07 AM Willem de Bruijn
<willemdebruijn.kernel@...il.com> wrote:
>
> From: Willem de Bruijn <willemb@...gle.com>
>
> Tun in IFF_NAPI_FRAGS mode calls napi_gro_frags. Unlike netif_rx and
> netif_gro_receive, this expects skb->data to point to the mac layer.
>
> But skb_probe_transport_header, __skb_get_hash_symmetric, and
> xdp_do_generic in tun_get_user need skb->data to point to the network
> header. Flow dissection also needs skb->protocol set, so
> eth_type_trans has to be called.
>
> Temporarily pull ETH_HLEN to make control flow the same for frags and
> not frags. Then push the header just before calling napi_gro_frags.
>
> Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver")
> Signed-off-by: Willem de Bruijn <willemb@...gle.com>

Acked-by: Petar Penkov <ppenkov@...gle.com>

> ---
>  drivers/net/tun.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 44889eba1dbc..b984733c6c31 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1871,8 +1871,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>                 skb->dev = tun->dev;
>                 break;
>         case IFF_TAP:
> -               if (!frags)
> -                       skb->protocol = eth_type_trans(skb, tun->dev);
> +               if (frags && !pskb_may_pull(skb, ETH_HLEN)) {
> +                       err = -ENOMEM;
> +                       goto drop;
> +               }
> +               skb->protocol = eth_type_trans(skb, tun->dev);
>                 break;
>         }
>
> @@ -1929,9 +1932,12 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>         }
>
>         if (frags) {
> +               u32 headlen;
> +
>                 /* Exercise flow dissector code path. */
> -               u32 headlen = eth_get_headlen(tun->dev, skb->data,
> -                                             skb_headlen(skb));
> +               skb_push(skb, ETH_HLEN);
> +               headlen = eth_get_headlen(tun->dev, skb->data,
> +                                         skb_headlen(skb));
>
>                 if (unlikely(headlen > skb_headlen(skb))) {
>                         this_cpu_inc(tun->pcpu_stats->rx_dropped);
> --
> 2.27.0.rc0.183.gde8f92d652-goog
>

Powered by blists - more mailing lists