From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39548) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmkpu-0005dy-32 for qemu-devel@nongnu.org; Wed, 21 Sep 2016 12:57:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bmkpq-0002wu-UQ for qemu-devel@nongnu.org; Wed, 21 Sep 2016 12:57:30 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:48444) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmkpq-0002wc-L0 for qemu-devel@nongnu.org; Wed, 21 Sep 2016 12:57:26 -0400 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u8LGrTh3144027 for ; Wed, 21 Sep 2016 12:57:25 -0400 Received: from e35.co.us.ibm.com (e35.co.us.ibm.com [32.97.110.153]) by mx0a-001b2d01.pphosted.com with ESMTP id 25kqvpbngb-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 21 Sep 2016 12:57:25 -0400 Received: from localhost by e35.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 21 Sep 2016 10:57:20 -0600 From: Greg Kurz Date: Wed, 21 Sep 2016 18:57:12 +0200 In-Reply-To: <147447700612.30952.9420141963781948805.stgit@bahia> References: <147447700612.30952.9420141963781948805.stgit@bahia> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <147447703245.30952.11628276217402153393.stgit@bahia> Subject: [Qemu-devel] [PATCH v2 3/9] virtio-9p: handle handle_9p_output() error List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , "Michael S. Tsirkin" , Jason Wang , Greg Kurz , Max Reitz , "Aneesh Kumar K.V" , Stefan Hajnoczi , Cornelia Huck , Paolo Bonzini A broken guest may send a request with only non-empty out buffers or only non-empty in buffers, virtqueue_pop() will then return a VirtQueueElement with out_num == 0 or in_num == 0 respectively. All 9P requests are expected to start with the following 7-byte header: uint32_t size_le; uint8_t id; uint16_t tag_le; If iov_to_buf() fails to return these 7 bytes, then something is wrong in the guest. In both cases, it is wrong to crash QEMU, since the root cause lies in the guest. Let's switch the device to the broken state instead. Signed-off-by: Greg Kurz --- v2: - added out_free_pdu: label for errors or when virtqueue is empty --- hw/9pfs/virtio-9p-device.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index e7ea0e45f3dd..5f3a67cfc717 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -52,17 +52,24 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); if (!elem) { - pdu_free(pdu); - break; + goto out_free_pdu; } - BUG_ON(elem->out_num == 0 || elem->in_num == 0); + if (elem->out_num == 0 || elem->in_num == 0) { + virtio_error(vdev, + "The guest sent a VirtFS request without headers"); + goto out_free_pdu; + } QEMU_BUILD_BUG_ON(sizeof(out) != 7); v->elems[pdu->idx] = elem; len = iov_to_buf(elem->out_sg, elem->out_num, 0, &out, sizeof(out)); - BUG_ON(len != sizeof(out)); + if (len != sizeof(out)) { + virtio_error(vdev, "The guest sent a malformed VirtFS request: " + "header size is %zd, should be 7", len); + goto out_free_pdu; + } pdu->size = le32_to_cpu(out.size_le); @@ -72,6 +79,11 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) qemu_co_queue_init(&pdu->complete); pdu_submit(pdu); } + + return; + +out_free_pdu: + pdu_free(pdu); } static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features,