From patchwork Tue Apr 5 18:55:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Bligh X-Patchwork-Id: 8754541 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2BE39C0553 for ; Tue, 5 Apr 2016 18:55:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 037FB20373 for ; Tue, 5 Apr 2016 18:55:10 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4F1492035D for ; Tue, 5 Apr 2016 18:55:08 +0000 (UTC) Received: from localhost ([::1]:38821 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anW83-0002SP-Du for patchwork-qemu-devel@patchwork.kernel.org; Tue, 05 Apr 2016 14:55:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50437) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anW7w-0002S3-2o for qemu-devel@nongnu.org; Tue, 05 Apr 2016 14:55:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1anW7v-0001I7-0U for qemu-devel@nongnu.org; Tue, 05 Apr 2016 14:54:59 -0400 Received: from mail.avalus.com ([2001:41c8:10:1dd::10]:59609) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anW7u-0001I0-PU for qemu-devel@nongnu.org; Tue, 05 Apr 2016 14:54:58 -0400 Received: by mail.avalus.com (Postfix) with ESMTPSA id 0E97232A6005; Tue, 5 Apr 2016 19:54:57 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=alex.org.uk; s=mail; t=1459882497; bh=N0QXUzYlzIeFiyNbhEpIXmzo3F9MzJAQYNbuEkUmsms=; h=From:To:Cc:Subject:Date; b=d8DbkUZyG4ItcEq4baLW4AgBaudaBgGqZYisIabrioWaSYXHRPm/p+pvboyHFKYpT F4NGZZmgseF1P33N31ld2tMOUvH1CsH2gLxinwpFqdSNpi9lN9zveCTHapFcMn6lU3 W41yuTTUmJ17bLPrR19OJxOpv+k4VDdJfnxt5bAM= From: Alex Bligh To: "Daniel P. Berrange" , Paolo Bonzini , Kevin Wolf , Eric Blake , "qemu-devel@nongnu.org" Date: Tue, 5 Apr 2016 19:55:00 +0100 Message-Id: <1459882500-24316-1-git-send-email-alex@alex.org.uk> X-Mailer: git-send-email 1.9.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 2001:41c8:10:1dd::10 Cc: Wouter Verhelst , Alex Bligh Subject: [Qemu-devel] [PATCH] Fix NBD unsupported options X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP nbd-client.c currently fails to handle unsupported options properly. If during option haggling the server finds an option that is unsupported, it returns an NBD_REP_ERR_UNSUP reply. According to nbd's proto.md, the format for such a reply should be: S: 64 bits, 0x3e889045565a9 (magic number for replies) S: 32 bits, the option as sent by the client to which this is a reply S: 32 bits, reply type (e.g., NBD_REP_ACK for successful completion, or NBD_REP_ERR_UNSUP to mark use of an option not known by this server S: 32 bits, length of the reply. This may be zero for some replies, in which case the next field is not sent S: any data as required by the reply (e.g., an export name in the case of NBD_REP_SERVER) However, in nbd-client.c, the reply type was being read, and if it contained an error, it was bailing out and issuing the next option request without first reading the length. This meant that the next option / handshake read had an extra 4 bytes of data in it. In practice, this makes Qemu incompatible with servers that do not support NBD_OPT_LIST. To verify this isn't an error in the specification or my reading of it, replies are sent by the reference implementation here: https://github.com/yoe/nbd/blob/master/nbd-server.c#L1232 and as is evident it always sends a 'datasize' (aka length) 32 bit word. Unsupported elements are replied to here: https://github.com/yoe/nbd/blob/master/nbd-server.c#L1371 Signed-off-by: Alex Bligh Reviewed-by: Eric Blake --- nbd/client.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index d9b7a9b..6f0541d 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -138,12 +138,6 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) return -1; } type = be32_to_cpu(type); - if (type == NBD_REP_ERR_UNSUP) { - return 0; - } - if (nbd_handle_reply_err(opt, type, errp) < 0) { - return -1; - } if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) { error_setg(errp, "failed to read option length"); @@ -151,6 +145,13 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) } len = be32_to_cpu(len); + if (type == NBD_REP_ERR_UNSUP) { + return 0; + } + if (nbd_handle_reply_err(opt, type, errp) < 0) { + return -1; + } + if (type == NBD_REP_ACK) { if (len != 0) { error_setg(errp, "length too long for option end");