218e99
From 99ad3018eac4089569f5ccbc84737dce8e92384f Mon Sep 17 00:00:00 2001
218e99
From: Miroslav Rezanina <mrezanin@redhat.com>
218e99
Date: Wed, 31 Jul 2013 09:54:07 +0200
218e99
Subject: vmdk: Allow reading variable size descriptor files
218e99
218e99
Message-id: <1374654509-5535-3-git-send-email-famz@redhat.com>
218e99
Patchwork-id: 52674
218e99
O-Subject: [RHEL-7 qemu-kvm PATCH 2/5] vmdk: Allow reading variable size descriptor files
218e99
Bugzilla: 836675
218e99
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
218e99
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
218e99
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
218e99
218e99
From: Evgeny Budilovsky <evgeny.budilovsky@ravellosystems.com>
218e99
218e99
the hard-coded 2k buffer on the stack won't allow reading big descriptor
218e99
files which can be generated when storing big images. For example 500G
218e99
vmdk splitted to 2G chunks.
218e99
218e99
Signed-off-by: Evgeny Budilovsky <evgeny.budilovsky@ravellosystems.com>
218e99
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
218e99
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
218e99
(cherry picked from commit 0bed087df24c7b3fae366f239b9d150de3309416)
218e99
Signed-off-by: Fam Zheng <famz@redhat.com>
218e99
218e99
diff --git a/block/vmdk.c b/block/vmdk.c
218e99
index ee50a73..65ae011 100644
218e99
--- a/block/vmdk.c
218e99
+++ b/block/vmdk.c
218e99
@@ -722,27 +722,40 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
218e99
                                int64_t desc_offset)
218e99
 {
218e99
     int ret;
218e99
-    char buf[2048];
218e99
+    char *buf = NULL;
218e99
     char ct[128];
218e99
     BDRVVmdkState *s = bs->opaque;
218e99
+    int64_t size;
218e99
 
218e99
-    ret = bdrv_pread(bs->file, desc_offset, buf, sizeof(buf));
218e99
+    size = bdrv_getlength(bs->file);
218e99
+    if (size < 0) {
218e99
+        return -EINVAL;
218e99
+    }
218e99
+
218e99
+    size = MIN(size, 1 << 20);  /* avoid unbounded allocation */
218e99
+    buf = g_malloc0(size + 1);
218e99
+
218e99
+    ret = bdrv_pread(bs->file, desc_offset, buf, size);
218e99
     if (ret < 0) {
218e99
-        return ret;
218e99
+        goto exit;
218e99
     }
218e99
-    buf[2047] = '\0';
218e99
     if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
218e99
-        return -EMEDIUMTYPE;
218e99
+        ret = -EMEDIUMTYPE;
218e99
+        goto exit;
218e99
     }
218e99
     if (strcmp(ct, "monolithicFlat") &&
218e99
         strcmp(ct, "twoGbMaxExtentSparse") &&
218e99
         strcmp(ct, "twoGbMaxExtentFlat")) {
218e99
         fprintf(stderr,
218e99
                 "VMDK: Not supported image type \"%s\""".\n", ct);
218e99
-        return -ENOTSUP;
218e99
+        ret = -ENOTSUP;
218e99
+        goto exit;
218e99
     }
218e99
     s->desc_offset = 0;
218e99
-    return vmdk_parse_extents(buf, bs, bs->file->filename);
218e99
+    ret = vmdk_parse_extents(buf, bs, bs->file->filename);
218e99
+exit:
218e99
+    g_free(buf);
218e99
+    return ret;
218e99
 }
218e99
 
218e99
 static int vmdk_open(BlockDriverState *bs, QDict *options, int flags)