From patchwork Tue Sep 20 09:41:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VG9tw6HFoSBHb2xlbWJpb3Zza8O9?= X-Patchwork-Id: 672179 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 ozlabs.org (Postfix) with ESMTPS id 3sddD44f8Dz9sD6 for ; Tue, 20 Sep 2016 19:45:40 +1000 (AEST) Received: from localhost ([::1]:33463 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmHcQ-0003t8-CM for incoming@patchwork.ozlabs.org; Tue, 20 Sep 2016 05:45:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55139) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmHYP-0000n5-OC for qemu-devel@nongnu.org; Tue, 20 Sep 2016 05:41:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bmHYN-0003zo-If for qemu-devel@nongnu.org; Tue, 20 Sep 2016 05:41:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60448) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmHYN-0003z2-8o for qemu-devel@nongnu.org; Tue, 20 Sep 2016 05:41:27 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BD17C3B3C5 for ; Tue, 20 Sep 2016 09:41:26 +0000 (UTC) Received: from fiorina (dhcp131-20.brq.redhat.com [10.34.131.20]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8K9fKD7028498 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 20 Sep 2016 05:41:26 -0400 Date: Tue, 20 Sep 2016 11:41:03 +0200 From: =?UTF-8?B?VG9tw6HFoSBHb2xlbWJpb3Zza8O9?= To: Paolo Bonzini , qemu-devel@nongnu.org Message-ID: <20160920114103.27aeea2a@fiorina> Organization: Red Hat MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 20 Sep 2016 09:41:26 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/2] qemu-nbd: Add --image-size option 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: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When image is part of the file it makes sense to limit the length of the image in the file. Otherwise it is assumed that the image spans to the end of the file. This assumption may lead to reads/writes outside of the image and thus lead to errors or data corruption. To limit the assumed image size new option is introduced. Signed-off-by: Tomáš Golembiovský --- qemu-nbd.c | 44 +++++++++++++++++++++++++++++++++++--------- qemu-nbd.texi | 4 ++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index 629bce1..7ed52f7 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -85,6 +85,7 @@ static void usage(const char *name) "\n" "Exposing part of the image:\n" " -o, --offset=OFFSET offset into the image\n" +" -S, --device-size=LEN limit reported device size\n" " -P, --partition=NUM only expose partition NUM\n" "\n" "General purpose options:\n" @@ -471,10 +472,12 @@ int main(int argc, char **argv) const char *port = NULL; char *sockpath = NULL; char *device = NULL; - off_t fd_size; + off_t real_size = 0; + off_t fd_size = 0; + bool has_image_size = false; QemuOpts *sn_opts = NULL; const char *sn_id_or_name = NULL; - const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:"; + const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:S:"; struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -482,6 +485,7 @@ int main(int argc, char **argv) { "port", required_argument, NULL, 'p' }, { "socket", required_argument, NULL, 'k' }, { "offset", required_argument, NULL, 'o' }, + { "image-size", required_argument, NULL, 'S' }, { "read-only", no_argument, NULL, 'r' }, { "partition", required_argument, NULL, 'P' }, { "connect", required_argument, NULL, 'c' }, @@ -714,6 +718,18 @@ int main(int argc, char **argv) g_free(trace_file); trace_file = trace_opt_parse(optarg); break; + case 'S': + ret = qemu_strtoll(optarg, NULL, 0, &fd_size); + if (ret != 0) { + error_report("Invalid image size `%s'", optarg); + exit(EXIT_FAILURE); + } + if (fd_size <= 0) { + error_report("Image size must be positive `%s'", optarg); + exit(EXIT_FAILURE); + } + has_image_size = true; + break; } } @@ -894,19 +910,29 @@ int main(int argc, char **argv) } bs->detect_zeroes = detect_zeroes; - fd_size = blk_getlength(blk); - if (fd_size < 0) { + real_size = blk_getlength(blk); + if (real_size < 0) { error_report("Failed to determine the image length: %s", - strerror(-fd_size)); + strerror(-real_size)); exit(EXIT_FAILURE); } - if (dev_offset >= fd_size) { - error_report("Offset (%lu) has to be smaller than the image size (%lu)", - dev_offset, fd_size); + if (!has_image_size) { + fd_size = real_size; + + if (dev_offset >= fd_size) { + error_report("Offset (%lu) has to be smaller than image size (%lu)", + dev_offset, fd_size); + exit(EXIT_FAILURE); + } + + fd_size -= dev_offset; + } else if ((dev_offset + fd_size) > real_size) { + error_report("Offset (%lu) plus image size (%lu) has to be smaller " + "than or equal to real image size (%lu)", + dev_offset, fd_size, real_size); exit(EXIT_FAILURE); } - fd_size -= dev_offset; if (partition != -1) { ret = find_partition(blk, partition, &dev_offset, &fd_size); diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 91ebf04..c589525 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -30,6 +30,10 @@ credentials for the qemu-nbd server. The TCP port to listen on (default @samp{10809}) @item -o, --offset=@var{offset} The offset into the image +@item -S, --image-size=@var{length} +The size of the image to present to client. This is useful in combination with +@var{-o} when the image is embedded in file but does not span to the end of the +file. @item -b, --bind=@var{iface} The interface to bind to (default @samp{0.0.0.0}) @item -k, --socket=@var{path}