From nobody Wed Nov 5 13:48:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1498200528363425.3250312678583; Thu, 22 Jun 2017 23:48:48 -0700 (PDT) Received: from localhost ([::1]:33825 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOIOb-0004sR-UF for importer@patchew.org; Fri, 23 Jun 2017 02:48:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47509) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOILX-00024z-SU for qemu-devel@nongnu.org; Fri, 23 Jun 2017 02:45:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dOILS-00087E-UP for qemu-devel@nongnu.org; Fri, 23 Jun 2017 02:45:35 -0400 Received: from 3.mo5.mail-out.ovh.net ([46.105.40.108]:41556) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dOILS-00086n-L9 for qemu-devel@nongnu.org; Fri, 23 Jun 2017 02:45:30 -0400 Received: from player695.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 1AAA0108243 for ; Fri, 23 Jun 2017 08:45:29 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player695.ha.ovh.net (Postfix) with ESMTPA id CC7BD460075; Fri, 23 Jun 2017 08:45:25 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 23 Jun 2017 08:45:25 +0200 Message-ID: <149820032558.7187.9574922678907797880.stgit@bahia.lan> In-Reply-To: <149820029273.7187.14110849422638329192.stgit@bahia.lan> References: <149820029273.7187.14110849422638329192.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 13333188173404740017 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeljedrleefgdduudekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.40.108 Subject: [Qemu-devel] [PATCH v4 3/4] virtio-9p: break device if buffers are misconfigured X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Greg Kurz , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 The 9P protocol is transport agnostic: if the guest misconfigured the buffers, the best we can do is to set the broken flag on the device. Since virtio_pdu_vmarshal() may be called by several active PDUs, we check if the transport isn't broken already to avoid printing extra error messages. Signed-off-by: Greg Kurz --- v4: - update changelog and add comment to explain why we check vdev->broken in virtio_pdu_vmarshal() - dropped uneeded vdev->broken check in virtio_pdu_vunmarshal() --- hw/9pfs/9p.c | 2 +- hw/9pfs/9p.h | 2 +- hw/9pfs/virtio-9p-device.c | 48 +++++++++++++++++++++++++++++++++++++++-= ---- hw/9pfs/xen-9p-backend.c | 3 ++- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index a0ae98f7ca6f..8e5cac71eb60 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1664,7 +1664,7 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qio= v, V9fsPDU *pdu, unsigned int niov; =20 if (is_write) { - pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov); + pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov, size + = skip); } else { pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, size + s= kip); } diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index aac1b0b2ce3d..d1cfeaf10e4f 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -363,7 +363,7 @@ struct V9fsTransport { void (*init_in_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, unsigned int *pniov, size_t size); void (*init_out_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, - unsigned int *pniov); + unsigned int *pniov, size_t size); void (*push_and_notify)(V9fsPDU *pdu); }; =20 diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 1a68c1622d3a..ed9e4817a26c 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -146,8 +146,22 @@ static ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_= t offset, V9fsState *s =3D pdu->s; V9fsVirtioState *v =3D container_of(s, V9fsVirtioState, state); VirtQueueElement *elem =3D v->elems[pdu->idx]; - - return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap= ); + int ret; + + ret =3D v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, a= p); + if (ret < 0) { + VirtIODevice *vdev =3D VIRTIO_DEVICE(v); + + /* Any active PDU may try to send something back to the client wit= hout + * knowing if the transport is broken or not. This could result in + * MAX_REQ - 1 (ie, 127) extra error messages being printed. + */ + if (!vdev->broken) { + virtio_error(vdev, "Failed to encode VirtFS reply type %d", + pdu->id + 1); + } + } + return ret; } =20 static ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset, @@ -156,28 +170,52 @@ static ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, si= ze_t offset, V9fsState *s =3D pdu->s; V9fsVirtioState *v =3D container_of(s, V9fsVirtioState, state); VirtQueueElement *elem =3D v->elems[pdu->idx]; + int ret; =20 - return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt= , ap); + ret =3D v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fm= t, ap); + if (ret < 0) { + VirtIODevice *vdev =3D VIRTIO_DEVICE(v); + + virtio_error(vdev, "Failed to decode VirtFS request type %d", pdu-= >id); + } + return ret; } =20 -/* The size parameter is used by other transports. Do not drop it. */ static void virtio_init_in_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, unsigned int *pniov, size_t size) { V9fsState *s =3D pdu->s; V9fsVirtioState *v =3D container_of(s, V9fsVirtioState, state); VirtQueueElement *elem =3D v->elems[pdu->idx]; + size_t buf_size =3D iov_size(elem->in_sg, elem->in_num); + + if (buf_size < size) { + VirtIODevice *vdev =3D VIRTIO_DEVICE(v); + + virtio_error(vdev, + "VirtFS reply type %d needs %zu bytes, buffer has %zu= ", + pdu->id + 1, size, buf_size); + } =20 *piov =3D elem->in_sg; *pniov =3D elem->in_num; } =20 static void virtio_init_out_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, - unsigned int *pniov) + unsigned int *pniov, size_t size) { V9fsState *s =3D pdu->s; V9fsVirtioState *v =3D container_of(s, V9fsVirtioState, state); VirtQueueElement *elem =3D v->elems[pdu->idx]; + size_t buf_size =3D iov_size(elem->out_sg, elem->out_num); + + if (buf_size < size) { + VirtIODevice *vdev =3D VIRTIO_DEVICE(v); + + virtio_error(vdev, + "VirtFS request type %d needs %zu bytes, buffer has %= zu", + pdu->id, size, buf_size); + } =20 *piov =3D elem->out_sg; *pniov =3D elem->out_num; diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 922cc967be63..a82cf817fe45 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -147,7 +147,8 @@ static ssize_t xen_9pfs_pdu_vunmarshal(V9fsPDU *pdu, =20 static void xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, - unsigned int *pniov) + unsigned int *pniov, + size_t size) { Xen9pfsDev *xen_9pfs =3D container_of(pdu->s, Xen9pfsDev, state); Xen9pfsRing *ring =3D &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings];