qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in


From: Markus Armbruster
Subject: [Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in bdrv_img_create()
Date: Mon, 7 Aug 2017 16:45:26 +0200

@size is declared int64_t.  It's set in two places.

The second one assigns the (signed) value of bdrv_getlength(), then
errors out if its negative.

The first one assigns qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0),
i.e. an uint64_t value.  What if it exceeds INT64_MAX?  Is that even
possible?  Turns out it is:

    $ qemu-img create -o size=9223372036854775808 foo.img

On closer examination, the code still works as long as converting from
uint64_t to int64_t and back doesn't change the value.
Implementation-defined behavior, but sane implementations behave.
Things actually break elsewhere for such sizes, e.g. file-posix.c's
raw_create().

Clean this up.

Signed-off-by: Markus Armbruster <address@hidden>
---
 block.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index ce9cce7..04cce0d 100644
--- a/block.c
+++ b/block.c
@@ -4309,7 +4309,8 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
     QemuOptsList *create_opts = NULL;
     QemuOpts *opts = NULL;
     const char *backing_fmt, *backing_file;
-    int64_t size;
+    uint64_t size;
+    int64_t backing_size;
     BlockDriver *drv, *proto_drv;
     Error *local_err = NULL;
     int ret = 0;
@@ -4414,7 +4415,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
         bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
                        &local_err);
         g_free(full_backing);
-        if (!bs && size != -1) {
+        if (!bs && size != UINT64_MAX) {
             /* Couldn't open BS, but we have a size, so it's nonfatal */
             warn_reportf_err(local_err,
                             "Could not verify backing image. "
@@ -4426,22 +4427,24 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
                               "Could not open backing image to determine 
size.\n");
             goto out;
         } else {
-            if (size == -1) {
+            if (size == UINT64_MAX) {
                 /* Opened BS, have no size */
-                size = bdrv_getlength(bs);
-                if (size < 0) {
-                    error_setg_errno(errp, -size, "Could not get size of '%s'",
+                backing_size = bdrv_getlength(bs);
+                if (backing_size < 0) {
+                    error_setg_errno(errp, -backing_size,
+                                     "Could not get size of '%s'",
                                      backing_file);
                     bdrv_unref(bs);
                     goto out;
                 }
+                size = backing_size;
                 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
             }
             bdrv_unref(bs);
         }
     } /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
 
-    if (size == -1) {
+    if (size == UINT64_MAX) {
         error_setg(errp, "Image creation needs a size parameter");
         goto out;
     }
-- 
2.7.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]