From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoeXl-0001oF-Tc for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aoeXi-0007SG-Vs for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45516) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoeXi-0007SA-Qh for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:18 -0400 From: Eric Blake Date: Fri, 8 Apr 2016 16:05:42 -0600 Message-Id: <1460153158-21612-3-git-send-email-eblake@redhat.com> In-Reply-To: <1460153158-21612-1-git-send-email-eblake@redhat.com> References: <1460153158-21612-1-git-send-email-eblake@redhat.com> Subject: [Qemu-devel] [PATCH 02/18] nbd: Don't fail handshake on NBD_OPT_LIST descriptions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: alex@alex.org.uk, Paolo Bonzini The NBD Protocol states that NBD_REP_SERVER may set 'length > sizeof(namelen) + namelen'; in which case the rest of the packet is a UTF-8 description of the export. While we don't know of any NBD servers that send this description yet, we had better consume the data so we don't choke when we start to talk to such a server. Also, a (buggy/malicious) server that replies with length < sizeof(namelen) would cause us to block waiting for bytes that the server is not sending, and one that replies with super-huge lengths could cause us to temporarily allocate up to 4G memory. Sanity check things before blindly reading incorrectly. Signed-off-by: Eric Blake --- nbd/client.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 6777e58..48f2a21 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -192,13 +192,18 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) return -1; } } else if (type == NBD_REP_SERVER) { + if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) { + error_setg(errp, "incorrect option length"); + return -1; + } if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) { error_setg(errp, "failed to read option name length"); return -1; } namelen = be32_to_cpu(namelen); - if (len != (namelen + sizeof(namelen))) { - error_setg(errp, "incorrect option mame length"); + len -= sizeof(namelen); + if (len < namelen) { + error_setg(errp, "incorrect option name length"); return -1; } if (namelen > 255) { @@ -214,6 +219,20 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) return -1; } (*name)[namelen] = '\0'; + len -= namelen; + if (len) { + char *buf = g_malloc(len + 1); + if (read_sync(ioc, buf, len) != len) { + error_setg(errp, "failed to read export description"); + g_free(*name); + g_free(buf); + *name = NULL; + return -1; + } + buf[len] = '\0'; + TRACE("Ignoring export description: %s", buf); + g_free(buf); + } } else { error_setg(errp, "Unexpected reply type %x expected %x", type, NBD_REP_SERVER); -- 2.5.5