From patchwork Fri Apr 13 19:26:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nir Soffer X-Patchwork-Id: 10340725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 79A39600D0 for ; Fri, 13 Apr 2018 19:29:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6821228797 for ; Fri, 13 Apr 2018 19:29:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5C1D028813; Fri, 13 Apr 2018 19:29:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id BC69F28797 for ; Fri, 13 Apr 2018 19:29:24 +0000 (UTC) Received: from localhost ([::1]:48041 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f74Nv-0007pv-W5 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 13 Apr 2018 15:29:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37340) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f74Kw-000583-Ko for qemu-devel@nongnu.org; Fri, 13 Apr 2018 15:26:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f74Kv-0001qh-0T for qemu-devel@nongnu.org; Fri, 13 Apr 2018 15:26:18 -0400 Received: from mail-wr0-x22a.google.com ([2a00:1450:400c:c0c::22a]:37823) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1f74Ku-0001pP-NF; Fri, 13 Apr 2018 15:26:16 -0400 Received: by mail-wr0-x22a.google.com with SMTP id l49so10728681wrl.4; Fri, 13 Apr 2018 12:26:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xpfMRyaNNR83VE+LH5SQPSq2G4HlPTWPkWuYA138rgU=; b=p20xV8+9D5AWFubg4ghjkAun8MtlKi0LlW6oxSI3pJTMwVnD0hu9Vja7vb/J7DCbkH jEsEVUO6DhpbakkVh8jwAiIBf4Nncg8FUDm9GAVQ1xd2AV8NlfdiJXIQZbGtWO/4SyEA ajfpn3HJCsvn+gymLOCAgOmNcGrrVTK93Lq3AUoeaQAuXsA6rdKsrjFENVDTxx8c+Lk4 FHcdOLcMUm0sWK3rykuKLXw6nhAEEI4BICG6QK1NbNZxGbd8SUAwSUtbXXoU1SRn1d7r 1IhlTH45MJs6LT9C7l+g0IhpYb2b4Nn4cgT4WtA0jfhKCBedrtuncaA3d3FSEJGB1GZK CNoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xpfMRyaNNR83VE+LH5SQPSq2G4HlPTWPkWuYA138rgU=; b=VPzLDrLyzXkNeBm0qHWuB/XW8liEwWWewvwtN1h/VdLeC8ksq4Rf62yieqEm9iC9ft Q4THz59T/UGkdZUfVT6AvYDQcRRYQ4p6o5rWqrCLz2Z75LrmPljFdKUyMUecJ0fve9yT 0tGwNvZ8WeKVPtQRYqYV49XdyX6tK17xNkn+hpFY/rzov/65IKLFbikZYVx8CbInn/Io WQ3/5+t8v8LfrVugLfUriFmP4PRlfGYY2GR2gkP/7IxokQLUu8bN9uiZRT51KbBuEhs7 ZRb9coDNFtm6okHnujYGnCSO41LbLYww3qB8wKTYdK+TrO3BwVi5+0ACu6EjpLsOGvHt FB3Q== X-Gm-Message-State: ALQs6tD5bOz2Pj+5lnU+aoQ+LVmK2Ud9tfSoBGhKf2oDtCGGbBcIi3ar GmyMf2na8m5y8RshsWXmI9BMHBwun8I= X-Google-Smtp-Source: AIpwx49chDWEfUm+XNZuhi84kransWZ6l+SxZjjMhmvYk7nj3jTaVIBgQh30LWZfqDKkgSNq50//Qg== X-Received: by 10.223.155.136 with SMTP id d8mr2316709wrc.132.1523647575162; Fri, 13 Apr 2018 12:26:15 -0700 (PDT) Received: from lean.local (93-173-127-3.bb.netvision.net.il. [93.173.127.3]) by smtp.gmail.com with ESMTPSA id r200sm842127wmb.39.2018.04.13.12.26.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 13 Apr 2018 12:26:14 -0700 (PDT) From: Nir Soffer To: qemu-devel@nongnu.org Date: Fri, 13 Apr 2018 22:26:03 +0300 Message-Id: <20180413192605.2145-2-nirsof@gmail.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180413192605.2145-1-nirsof@gmail.com> References: <20180413192605.2145-1-nirsof@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::22a Subject: [Qemu-devel] [PATCH 1/3] nbd: Add option to disallow listing exports 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: kwolf@redhat.com, Nir Soffer , qemu-block@nongnu.org, rjones@redhat.com, mreitz@redhat.com, pbonzini@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When a management application expose images using qemu-nbd, it needs a secure way to allow temporary access to the disk. Using a random export name can solve this problem: nbd://server:10809/22965f19-9ab5-4d18-94e1-cbeb321fa433 Assuming that the url is passed to the user in a secure way, and the user is using TLS to access the image. However, since qemu-nbd implements NBD_OPT_LIST, anyone can easily find the secret export: $ nbd-client -l server 10809 Negotiation: .. 22965f19-9ab5-4d18-94e1-cbeb321fa433 Add a new --nolist option, disabling listing, similar the "allowlist" nbd-server configuration option. When used, listing exports will fail like this: $ nbd-client -l localhost 10809 Negotiation: .. E: listing not allowed by server. Server said: Listing exports is forbidden Signed-off-by: Nir Soffer Tested-by: Richard W.M. Jones --- blockdev-nbd.c | 2 +- include/block/nbd.h | 1 + nbd/server.c | 7 +++++++ qemu-nbd.c | 9 ++++++++- qemu-nbd.texi | 2 ++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 65a84739ed..b9a885dc4b 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -37,7 +37,7 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, { qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server"); nbd_client_new(NULL, cioc, - nbd_server->tlscreds, NULL, + nbd_server->tlscreds, NULL, true, nbd_blockdev_client_closed); } diff --git a/include/block/nbd.h b/include/block/nbd.h index fcdcd54502..5c6b6272a0 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -308,6 +308,7 @@ void nbd_client_new(NBDExport *exp, QIOChannelSocket *sioc, QCryptoTLSCreds *tlscreds, const char *tlsaclname, + bool allow_list, void (*close_fn)(NBDClient *, bool)); void nbd_client_get(NBDClient *client); void nbd_client_put(NBDClient *client); diff --git a/nbd/server.c b/nbd/server.c index 9e1f227178..7b91922d1d 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -115,6 +115,7 @@ struct NBDClient { bool structured_reply; NBDExportMetaContexts export_meta; + bool allow_list; uint32_t opt; /* Current option being negotiated */ uint32_t optlen; /* remaining length of data in ioc for the option being @@ -1032,6 +1033,10 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags, case NBD_OPT_LIST: if (length) { ret = nbd_reject_length(client, false, errp); + } else if (!client->allow_list) { + ret = nbd_negotiate_send_rep_err(client, + NBD_REP_ERR_POLICY, errp, + "Listing exports is forbidden"); } else { ret = nbd_negotiate_handle_list(client, errp); } @@ -2141,6 +2146,7 @@ void nbd_client_new(NBDExport *exp, QIOChannelSocket *sioc, QCryptoTLSCreds *tlscreds, const char *tlsaclname, + bool allow_list, void (*close_fn)(NBDClient *, bool)) { NBDClient *client; @@ -2158,6 +2164,7 @@ void nbd_client_new(NBDExport *exp, object_ref(OBJECT(client->sioc)); client->ioc = QIO_CHANNEL(sioc); object_ref(OBJECT(client->ioc)); + client->allow_list = allow_list; client->close_fn = close_fn; co = qemu_coroutine_create(nbd_co_client_start, client); diff --git a/qemu-nbd.c b/qemu-nbd.c index 0af0560ad1..b63d4d9e8b 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -52,6 +52,7 @@ #define QEMU_NBD_OPT_TLSCREDS 261 #define QEMU_NBD_OPT_IMAGE_OPTS 262 #define QEMU_NBD_OPT_FORK 263 +#define QEMU_NBD_OPT_NOLIST 264 #define MBR_SIZE 512 @@ -66,6 +67,7 @@ static int shared = 1; static int nb_fds; static QIONetListener *server; static QCryptoTLSCreds *tlscreds; +static bool allow_list = true; static void usage(const char *name) { @@ -86,6 +88,7 @@ static void usage(const char *name) " -v, --verbose display extra debugging information\n" " -x, --export-name=NAME expose export by name\n" " -D, --description=TEXT with -x, also export a human-readable description\n" +" --nolist do not list export\n" "\n" "Exposing part of the image:\n" " -o, --offset=OFFSET offset into the image\n" @@ -355,7 +358,7 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, nb_fds++; nbd_update_server_watch(); nbd_client_new(newproto ? NULL : exp, cioc, - tlscreds, NULL, nbd_client_closed); + tlscreds, NULL, allow_list, nbd_client_closed); } static void nbd_update_server_watch(void) @@ -523,6 +526,7 @@ int main(int argc, char **argv) { "object", required_argument, NULL, QEMU_NBD_OPT_OBJECT }, { "export-name", required_argument, NULL, 'x' }, { "description", required_argument, NULL, 'D' }, + { "nolist", no_argument, NULL, QEMU_NBD_OPT_NOLIST }, { "tls-creds", required_argument, NULL, QEMU_NBD_OPT_TLSCREDS }, { "image-opts", no_argument, NULL, QEMU_NBD_OPT_IMAGE_OPTS }, { "trace", required_argument, NULL, 'T' }, @@ -717,6 +721,9 @@ int main(int argc, char **argv) case 'D': export_description = optarg; break; + case QEMU_NBD_OPT_NOLIST: + allow_list = false; + break; case 'v': verbose = 1; break; diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 9a84e81eed..010b29588f 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -85,6 +85,8 @@ the new style NBD protocol negotiation @item -D, --description=@var{description} Set the NBD volume export description, as a human-readable string. Requires the use of @option{-x} +@item --nolist +Do not allow the client to fetch a list of exports from this server. @item --tls-creds=ID Enable mandatory TLS encryption for the server by setting the ID of the TLS credentials object previously created with the --object