summaryrefslogtreecommitdiffstats
path: root/net-vhost_net-fix-possible-infinite-loop.patch
diff options
context:
space:
mode:
authorJustin M. Forbes <jforbes@fedoraproject.org>2019-06-04 11:15:33 -0500
committerJustin M. Forbes <jforbes@fedoraproject.org>2019-06-04 11:15:33 -0500
commitdf15d2b71a4373c57da73a58848ef607d25611a1 (patch)
tree2911145aad402b4810608f1f30ddec2de8fdf53d /net-vhost_net-fix-possible-infinite-loop.patch
parent76165d2da83586014484999bd29df948e4357b26 (diff)
downloadkernel-df15d2b71a4373c57da73a58848ef607d25611a1.tar.gz
kernel-df15d2b71a4373c57da73a58848ef607d25611a1.tar.xz
kernel-df15d2b71a4373c57da73a58848ef607d25611a1.zip
Linux v5.2-rc3-24-g788a024921c4
Diffstat (limited to 'net-vhost_net-fix-possible-infinite-loop.patch')
-rw-r--r--net-vhost_net-fix-possible-infinite-loop.patch200
1 files changed, 0 insertions, 200 deletions
diff --git a/net-vhost_net-fix-possible-infinite-loop.patch b/net-vhost_net-fix-possible-infinite-loop.patch
deleted file mode 100644
index f45d84bb2..000000000
--- a/net-vhost_net-fix-possible-infinite-loop.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From patchwork Thu Apr 25 07:33:19 2019
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Jason Wang <jasowang@redhat.com>
-X-Patchwork-Id: 10916185
-Return-Path: <kvm-owner@kernel.org>
-Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org
- [172.30.200.125])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4F501575
- for <patchwork-kvm@patchwork.kernel.org>;
- Thu, 25 Apr 2019 07:33:33 +0000 (UTC)
-Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1])
- by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D276828BD7
- for <patchwork-kvm@patchwork.kernel.org>;
- Thu, 25 Apr 2019 07:33:33 +0000 (UTC)
-Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486)
- id C64AC28BE1; Thu, 25 Apr 2019 07:33:33 +0000 (UTC)
-X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
- pdx-wl-mail.web.codeaurora.org
-X-Spam-Level:
-X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI,
- RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1
-Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
- by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 590B228BD7
- for <patchwork-kvm@patchwork.kernel.org>;
- Thu, 25 Apr 2019 07:33:33 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S1726957AbfDYHd1 (ORCPT
- <rfc822;patchwork-kvm@patchwork.kernel.org>);
- Thu, 25 Apr 2019 03:33:27 -0400
-Received: from mx1.redhat.com ([209.132.183.28]:60130 "EHLO mx1.redhat.com"
- rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
- id S1726317AbfDYHd1 (ORCPT <rfc822;kvm@vger.kernel.org>);
- Thu, 25 Apr 2019 03:33:27 -0400
-Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com
- [10.5.11.22])
- (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
- (No client certificate requested)
- by mx1.redhat.com (Postfix) with ESMTPS id C2BCE3002619;
- Thu, 25 Apr 2019 07:33:26 +0000 (UTC)
-Received: from hp-dl380pg8-02.lab.eng.pek2.redhat.com
- (hp-dl380pg8-02.lab.eng.pek2.redhat.com [10.73.8.12])
- by smtp.corp.redhat.com (Postfix) with ESMTP id 5DA021001DDB;
- Thu, 25 Apr 2019 07:33:21 +0000 (UTC)
-From: Jason Wang <jasowang@redhat.com>
-To: mst@redhat.com, jasowang@redhat.com, kvm@vger.kernel.org,
- virtualization@lists.linux-foundation.org, netdev@vger.kernel.org,
- linux-kernel@vger.kernel.org
-Cc: ppandit@redhat.com
-Subject: [PATCH net] vhost_net: fix possible infinite loop
-Date: Thu, 25 Apr 2019 03:33:19 -0400
-Message-Id: <1556177599-56248-1-git-send-email-jasowang@redhat.com>
-X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22
-X-Greylist: Sender IP whitelisted,
- not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]);
- Thu, 25 Apr 2019 07:33:26 +0000 (UTC)
-Sender: kvm-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <kvm.vger.kernel.org>
-X-Mailing-List: kvm@vger.kernel.org
-X-Virus-Scanned: ClamAV using ClamSMTP
-
-When the rx buffer is too small for a packet, we will discard the vq
-descriptor and retry it for the next packet:
-
-while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk,
- &busyloop_intr))) {
-...
- /* On overrun, truncate and discard */
- if (unlikely(headcount > UIO_MAXIOV)) {
- iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1);
- err = sock->ops->recvmsg(sock, &msg,
- 1, MSG_DONTWAIT | MSG_TRUNC);
- pr_debug("Discarded rx packet: len %zd\n", sock_len);
- continue;
- }
-...
-}
-
-This makes it possible to trigger a infinite while..continue loop
-through the co-opreation of two VMs like:
-
-1) Malicious VM1 allocate 1 byte rx buffer and try to slow down the
- vhost process as much as possible e.g using indirect descriptors or
- other.
-2) Malicious VM2 generate packets to VM1 as fast as possible
-
-Fixing this by checking against weight at the end of RX and TX
-loop. This also eliminate other similar cases when:
-
-- userspace is consuming the packets in the meanwhile
-- theoretical TOCTOU attack if guest moving avail index back and forth
- to hit the continue after vhost find guest just add new buffers
-
-This addresses CVE-2019-3900.
-
-Fixes: d8316f3991d20 ("vhost: fix total length when packets are too short")
-Fixes: 3a4d5c94e9593 ("vhost_net: a kernel-level virtio server")
-Signed-off-by: Jason Wang <jasowang@redhat.com>
----
- drivers/vhost/net.c | 41 +++++++++++++++++++++--------------------
- 1 file changed, 21 insertions(+), 20 deletions(-)
-
-diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
-index df51a35..fb46e6b 100644
---- a/drivers/vhost/net.c
-+++ b/drivers/vhost/net.c
-@@ -778,8 +778,9 @@ static void handle_tx_copy(struct vhost_net *net, struct socket *sock)
- int err;
- int sent_pkts = 0;
- bool sock_can_batch = (sock->sk->sk_sndbuf == INT_MAX);
-+ bool next_round = false;
-
-- for (;;) {
-+ do {
- bool busyloop_intr = false;
-
- if (nvq->done_idx == VHOST_NET_BATCH)
-@@ -845,11 +846,10 @@ static void handle_tx_copy(struct vhost_net *net, struct socket *sock)
- vq->heads[nvq->done_idx].id = cpu_to_vhost32(vq, head);
- vq->heads[nvq->done_idx].len = 0;
- ++nvq->done_idx;
-- if (vhost_exceeds_weight(++sent_pkts, total_len)) {
-- vhost_poll_queue(&vq->poll);
-- break;
-- }
-- }
-+ } while (!(next_round = vhost_exceeds_weight(++sent_pkts, total_len)));
-+
-+ if (next_round)
-+ vhost_poll_queue(&vq->poll);
-
- vhost_tx_batch(net, nvq, sock, &msg);
- }
-@@ -873,8 +873,9 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock)
- struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
- bool zcopy_used;
- int sent_pkts = 0;
-+ bool next_round = false;
-
-- for (;;) {
-+ do {
- bool busyloop_intr;
-
- /* Release DMAs done buffers first */
-@@ -951,11 +952,10 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock)
- else
- vhost_zerocopy_signal_used(net, vq);
- vhost_net_tx_packet(net);
-- if (unlikely(vhost_exceeds_weight(++sent_pkts, total_len))) {
-- vhost_poll_queue(&vq->poll);
-- break;
-- }
-- }
-+ } while (!(next_round = vhost_exceeds_weight(++sent_pkts, total_len)));
-+
-+ if (next_round)
-+ vhost_poll_queue(&vq->poll);
- }
-
- /* Expects to be always run from workqueue - which acts as
-@@ -1134,6 +1134,7 @@ static void handle_rx(struct vhost_net *net)
- struct iov_iter fixup;
- __virtio16 num_buffers;
- int recv_pkts = 0;
-+ bool next_round = false;
-
- mutex_lock_nested(&vq->mutex, VHOST_NET_VQ_RX);
- sock = vq->private_data;
-@@ -1153,8 +1154,11 @@ static void handle_rx(struct vhost_net *net)
- vq->log : NULL;
- mergeable = vhost_has_feature(vq, VIRTIO_NET_F_MRG_RXBUF);
-
-- while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk,
-- &busyloop_intr))) {
-+ do {
-+ sock_len = vhost_net_rx_peek_head_len(net, sock->sk,
-+ &busyloop_intr);
-+ if (!sock_len)
-+ break;
- sock_len += sock_hlen;
- vhost_len = sock_len + vhost_hlen;
- headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
-@@ -1239,12 +1243,9 @@ static void handle_rx(struct vhost_net *net)
- vhost_log_write(vq, vq_log, log, vhost_len,
- vq->iov, in);
- total_len += vhost_len;
-- if (unlikely(vhost_exceeds_weight(++recv_pkts, total_len))) {
-- vhost_poll_queue(&vq->poll);
-- goto out;
-- }
-- }
-- if (unlikely(busyloop_intr))
-+ } while (!(next_round = vhost_exceeds_weight(++recv_pkts, total_len)));
-+
-+ if (unlikely(busyloop_intr || next_round))
- vhost_poll_queue(&vq->poll);
- else
- vhost_net_enable_vq(net, vq);