[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cbac7eca-c72f-2e64-5ec1-45ce414f0d7b@redhat.com>
Date: Wed, 23 Jun 2021 11:48:43 +0800
From: Jason Wang <jasowang@...hat.com>
To: David Woodhouse <dwmw2@...radead.org>, netdev@...r.kernel.org
Cc: Eugenio Pérez <eperezma@...hat.com>
Subject: Re: [PATCH v2 3/4] vhost_net: validate virtio_net_hdr only if it
exists
在 2021/6/23 上午12:15, David Woodhouse 写道:
> From: David Woodhouse <dwmw@...zon.co.uk>
>
> When the underlying socket doesn't handle the virtio_net_hdr, the
> existing code in vhost_net_build_xdp() would attempt to validate stack
> noise, by copying zero bytes into the local copy of the header and then
> validating that. Skip the whole pointless pointer arithmetic and partial
> copy (of zero bytes) in this case.
>
> Fixes: 0a0be13b8fe2 ("vhost_net: batch submitting XDP buffers to underlayer sockets")
> Signed-off-by: David Woodhouse <dwmw@...zon.co.uk>
Acked-by: Jason Wang <jasowang@...hat.com>
> ---
> drivers/vhost/net.c | 43 ++++++++++++++++++++++---------------------
> 1 file changed, 22 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index df82b124170e..1e3652eb53af 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -690,7 +690,6 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq,
> dev);
> struct socket *sock = vhost_vq_get_backend(vq);
> struct page_frag *alloc_frag = &net->page_frag;
> - struct virtio_net_hdr *gso;
> struct xdp_buff *xdp = &nvq->xdp[nvq->batched_xdp];
> struct tun_xdp_hdr *hdr;
> size_t len = iov_iter_count(from);
> @@ -715,29 +714,31 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq,
> return -ENOMEM;
>
> buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
> - copied = copy_page_from_iter(alloc_frag->page,
> - alloc_frag->offset +
> - offsetof(struct tun_xdp_hdr, gso),
> - sock_hlen, from);
> - if (copied != sock_hlen)
> - return -EFAULT;
> -
> hdr = buf;
> - gso = &hdr->gso;
> -
> - if ((gso->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
> - vhost16_to_cpu(vq, gso->csum_start) +
> - vhost16_to_cpu(vq, gso->csum_offset) + 2 >
> - vhost16_to_cpu(vq, gso->hdr_len)) {
> - gso->hdr_len = cpu_to_vhost16(vq,
> - vhost16_to_cpu(vq, gso->csum_start) +
> - vhost16_to_cpu(vq, gso->csum_offset) + 2);
> -
> - if (vhost16_to_cpu(vq, gso->hdr_len) > len)
> - return -EINVAL;
> + if (sock_hlen) {
> + struct virtio_net_hdr *gso = &hdr->gso;
> +
> + copied = copy_page_from_iter(alloc_frag->page,
> + alloc_frag->offset +
> + offsetof(struct tun_xdp_hdr, gso),
> + sock_hlen, from);
> + if (copied != sock_hlen)
> + return -EFAULT;
> +
> + if ((gso->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
> + vhost16_to_cpu(vq, gso->csum_start) +
> + vhost16_to_cpu(vq, gso->csum_offset) + 2 >
> + vhost16_to_cpu(vq, gso->hdr_len)) {
> + gso->hdr_len = cpu_to_vhost16(vq,
> + vhost16_to_cpu(vq, gso->csum_start) +
> + vhost16_to_cpu(vq, gso->csum_offset) + 2);
> +
> + if (vhost16_to_cpu(vq, gso->hdr_len) > len)
> + return -EINVAL;
> + }
> + len -= sock_hlen;
> }
>
> - len -= sock_hlen;
> copied = copy_page_from_iter(alloc_frag->page,
> alloc_frag->offset + pad,
> len, from);
Powered by blists - more mailing lists