qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Tomáš Golembiovský" <tgolembi@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 2/2] qemu-nbd: Add --image-size option
Date: Tue, 20 Sep 2016 11:41:03 +0200	[thread overview]
Message-ID: <20160920114103.27aeea2a@fiorina> (raw)

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ý <tgolembi@redhat.com>
---
 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}
-- 
2.9.3

             reply	other threads:[~2016-09-20  9:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-20  9:41 Tomáš Golembiovský [this message]
2016-09-20  9:59 ` [Qemu-devel] [PATCH 2/2] qemu-nbd: Add --image-size option Paolo Bonzini
2016-09-20 11:12   ` Daniel P. Berrange
2016-09-20 11:45     ` Paolo Bonzini
2016-10-02 19:33       ` Tomáš Golembiovský
2016-09-20 11:35   ` Tomáš Golembiovský
2016-09-20 12:45     ` Richard W.M. Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160920114103.27aeea2a@fiorina \
    --to=tgolembi@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).