From 1f2803c94752a8f6bb9afc53b1f8b8e778b947d4 Mon Sep 17 00:00:00 2001 Message-Id: <1f2803c94752a8f6bb9afc53b1f8b8e778b947d4.1369658547.git.minovotn@redhat.com> In-Reply-To: <07146f8b79923c529fd93fa528e6fcbd6f571a02.1369658547.git.minovotn@redhat.com> References: <07146f8b79923c529fd93fa528e6fcbd6f571a02.1369658547.git.minovotn@redhat.com> From: Fam Zheng Date: Mon, 20 May 2013 03:36:18 +0200 Subject: [PATCH 03/47] vmdk: fix endianness bugs RH-Author: Fam Zheng Message-id: <1369021022-22728-4-git-send-email-famz@redhat.com> Patchwork-id: 51439 O-Subject: [PATCH RHEL-6.5 qemu-kvm v3 03/47] vmdk: fix endianness bugs Bugzilla: 960685 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Jeffrey Cody RH-Acked-by: Kevin Wolf From: Alexander Graf The vmdk code is sloppy when handling the header descriptor during creation of an image. Fix all header accesses in the create path to either store native endianness or convert it when appropriate. Reported-by: Yury Tsarev Signed-off-by: Alexander Graf Signed-off-by: Kevin Wolf (cherry picked from commit 16372ff03d71c7ed3283f0e873ea0727a35810a9) Signed-off-by: Fam Zheng --- block/vmdk.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) Signed-off-by: Michal Novotny --- block/vmdk.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 733e7d3..c447216 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -744,11 +744,11 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) return -errno; magic = cpu_to_be32(VMDK4_MAGIC); memset(&header, 0, sizeof(header)); - header.version = cpu_to_le32(1); - header.flags = cpu_to_le32(3); /* ?? */ - header.capacity = cpu_to_le64(total_size); - header.granularity = cpu_to_le64(128); - header.num_gtes_per_gte = cpu_to_le32(512); + header.version = 1; + header.flags = 3; /* ?? */ + header.capacity = total_size; + header.granularity = 128; + header.num_gtes_per_gte = 512; grains = (total_size + header.granularity - 1) / header.granularity; gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9; @@ -764,6 +764,12 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) header.granularity - 1) / header.granularity) * header.granularity; + /* swap endianness for all header fields */ + header.version = cpu_to_le32(header.version); + header.flags = cpu_to_le32(header.flags); + header.capacity = cpu_to_le64(header.capacity); + header.granularity = cpu_to_le64(header.granularity); + header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte); header.desc_offset = cpu_to_le64(header.desc_offset); header.desc_size = cpu_to_le64(header.desc_size); header.rgd_offset = cpu_to_le64(header.rgd_offset); @@ -787,7 +793,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) goto exit; } - ret = ftruncate(fd, header.grain_offset << 9); + ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9); if (ret < 0) { ret = -errno; goto exit; @@ -795,7 +801,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) /* write grain directory */ lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET); - for (i = 0, tmp = header.rgd_offset + gd_size; + for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size; i < gt_count; i++, tmp += gt_size) { ret = qemu_write_full(fd, &tmp, sizeof(tmp)); if (ret != sizeof(tmp)) { @@ -806,7 +812,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) /* write backup grain directory */ lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET); - for (i = 0, tmp = header.gd_offset + gd_size; + for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size; i < gt_count; i++, tmp += gt_size) { ret = qemu_write_full(fd, &tmp, sizeof(tmp)); if (ret != sizeof(tmp)) { -- 1.7.11.7