lkml.org 
[lkml]   [2020]   [Jun]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 11/34] net: be more gentle about silly gso requests coming from user
    Date
    From: Eric Dumazet <edumazet@google.com>

    [ Upstream commit 7c6d2ecbda83150b2036a2b36b21381ad4667762 ]

    Recent change in virtio_net_hdr_to_skb() broke some packetdrill tests.

    When --mss=XXX option is set, packetdrill always provide gso_type & gso_size
    for its inbound packets, regardless of packet size.

    if (packet->tcp && packet->mss) {
    if (packet->ipv4)
    gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
    else
    gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
    gso.gso_size = packet->mss;
    }

    Since many other programs could do the same, relax virtio_net_hdr_to_skb()
    to no longer return an error, but instead ignore gso settings.

    This keeps Willem intent to make sure no malicious packet could
    reach gso stack.

    Note that TCP stack has a special logic in tcp_set_skb_tso_segs()
    to clear gso_size for small packets.

    Fixes: 6dd912f82680 ("net: check untrusted gso_size at kernel entry")
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Cc: Willem de Bruijn <willemb@google.com>
    Acked-by: Willem de Bruijn <willemb@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    include/linux/virtio_net.h | 17 +++++++++--------
    1 file changed, 9 insertions(+), 8 deletions(-)

    --- a/include/linux/virtio_net.h
    +++ b/include/linux/virtio_net.h
    @@ -109,16 +109,17 @@ retry:

    if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
    u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
    + struct skb_shared_info *shinfo = skb_shinfo(skb);

    - if (skb->len - p_off <= gso_size)
    - return -EINVAL;
    + /* Too small packets are not really GSO ones. */
    + if (skb->len - p_off > gso_size) {
    + shinfo->gso_size = gso_size;
    + shinfo->gso_type = gso_type;

    - skb_shinfo(skb)->gso_size = gso_size;
    - skb_shinfo(skb)->gso_type = gso_type;
    -
    - /* Header must be checked, and gso_segs computed. */
    - skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
    - skb_shinfo(skb)->gso_segs = 0;
    + /* Header must be checked, and gso_segs computed. */
    + shinfo->gso_type |= SKB_GSO_DODGY;
    + shinfo->gso_segs = 0;
    + }
    }

    return 0;

    \
     
     \ /
      Last update: 2020-06-09 20:05    [W:4.024 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site