From patchwork Tue May 24 22:46:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: vmdk: fix endianness bugs Date: Tue, 24 May 2011 12:46:55 -0000 From: Alexander Graf X-Patchwork-Id: 97242 Message-Id: <1306277215-17654-2-git-send-email-agraf@suse.de> To: "qemu-devel@nongnu.org Developers" Cc: Kevin Wolf 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 --- block/vmdk.c | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 8fc9d67..922b23d 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -716,11 +716,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; @@ -736,6 +736,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); @@ -759,7 +765,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; @@ -767,7 +773,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)) { @@ -778,7 +784,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)) {