From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60523) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0RcP-0001AK-2U for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:34:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X0RcI-0001Gn-Ui for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:34:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:19019) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0RcI-0001GW-NR for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:34:42 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5R8Yfa7011520 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 27 Jun 2014 04:34:41 -0400 From: "Dr. David Alan Gilbert (git)" Date: Fri, 27 Jun 2014 09:34:38 +0100 Message-Id: <1403858078-3402-1-git-send-email-dgilbert@redhat.com> Subject: [Qemu-devel] [PATCH] Allow mismatched virtio config-len List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, quintela@redhat.com, mst@redhat.com From: "Dr. David Alan Gilbert" Commit 'virtio: validate config_len on load' restricted config_len loaded from the wire to match the config_len that the device had. Unfortunately, there are cases where this isn't true, the one we found it on was the wqe addition in virtio-blk. Allow mismatched config-lengths: *) If the version on the wire is shorter then ensure that the remainder is 0xff filled (as virtio_config_read does on out of range reads) *) If the version on the wire is longer, load what we have space for and skip the rest. Signed-off-by: Dr. David Alan Gilbert --- hw/virtio/virtio.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index a3082d5..2b11142 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -927,11 +927,33 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) } config_len = qemu_get_be32(f); if (config_len != vdev->config_len) { - error_report("Unexpected config length 0x%x. Expected 0x%zx", - config_len, vdev->config_len); - return -1; + /* + * Unfortunately the reality is that there are cases where we + * see mismatched config lengths, so we have to deal with them + * rather than rejecting them. + */ + + if (config_len < vdev->config_len) { + /* This is normal in some devices when they add a new option */ + memset(vdev->config, 0xff, vdev->config_len); + qemu_get_buffer(f, vdev->config, config_len); + } else { + int32_t diff; + /* config_len > vdev->config_len + * This is rarer, but is here to allow us to fix the case above + */ + qemu_get_buffer(f, vdev->config, vdev->config_len); + /* + * Even though we expect the diff to be small, we can't use + * qemu_file_skip because it's not safe for a large skip. + */ + for (diff = config_len - vdev->config_len; diff > 0; diff--) { + qemu_get_byte(f); + } + } + } else { + qemu_get_buffer(f, vdev->config, vdev->config_len); } - qemu_get_buffer(f, vdev->config, vdev->config_len); num = qemu_get_be32(f); -- 1.9.3