block/vdi: Don't take address of fields in packed structs

Taking the address of a field in a packed struct is a bad idea, because
it might not be actually aligned enough for that pointer type (and
thus cause a crash on dereference on some host architectures). Newer
versions of clang warn about this.

Instead of passing UUID related functions the address of a possibly
unaligned QemuUUID struct, use local variables and then copy to/from
the struct field as appropriate.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Peter Maydell 2018-12-10 11:26:48 +00:00 committed by Kevin Wolf
parent 0dbaaa7981
commit ac928b8ee8

View file

@ -235,7 +235,8 @@ static void vdi_header_to_le(VdiHeader *header)
static void vdi_header_print(VdiHeader *header) static void vdi_header_print(VdiHeader *header)
{ {
char uuid[37]; char uuidstr[37];
QemuUUID uuid;
logout("text %s", header->text); logout("text %s", header->text);
logout("signature 0x%08x\n", header->signature); logout("signature 0x%08x\n", header->signature);
logout("header size 0x%04x\n", header->header_size); logout("header size 0x%04x\n", header->header_size);
@ -254,14 +255,18 @@ static void vdi_header_print(VdiHeader *header)
logout("block extra 0x%04x\n", header->block_extra); logout("block extra 0x%04x\n", header->block_extra);
logout("blocks tot. 0x%04x\n", header->blocks_in_image); logout("blocks tot. 0x%04x\n", header->blocks_in_image);
logout("blocks all. 0x%04x\n", header->blocks_allocated); logout("blocks all. 0x%04x\n", header->blocks_allocated);
qemu_uuid_unparse(&header->uuid_image, uuid); uuid = header->uuid_image;
logout("uuid image %s\n", uuid); qemu_uuid_unparse(&uuid, uuidstr);
qemu_uuid_unparse(&header->uuid_last_snap, uuid); logout("uuid image %s\n", uuidstr);
logout("uuid snap %s\n", uuid); uuid = header->uuid_last_snap;
qemu_uuid_unparse(&header->uuid_link, uuid); qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid link %s\n", uuid); logout("uuid snap %s\n", uuidstr);
qemu_uuid_unparse(&header->uuid_parent, uuid); uuid = header->uuid_link;
logout("uuid parent %s\n", uuid); qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid link %s\n", uuidstr);
uuid = header->uuid_parent;
qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid parent %s\n", uuidstr);
} }
static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res, static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
@ -368,6 +373,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
size_t bmap_size; size_t bmap_size;
int ret; int ret;
Error *local_err = NULL; Error *local_err = NULL;
QemuUUID uuid_link, uuid_parent;
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
false, errp); false, errp);
@ -395,6 +401,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
goto fail; goto fail;
} }
uuid_link = header.uuid_link;
uuid_parent = header.uuid_parent;
if (header.disk_size % SECTOR_SIZE != 0) { if (header.disk_size % SECTOR_SIZE != 0) {
/* 'VBoxManage convertfromraw' can create images with odd disk sizes. /* 'VBoxManage convertfromraw' can create images with odd disk sizes.
We accept them but round the disk size to the next multiple of We accept them but round the disk size to the next multiple of
@ -444,11 +453,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
(uint64_t)header.blocks_in_image * header.block_size); (uint64_t)header.blocks_in_image * header.block_size);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (!qemu_uuid_is_null(&header.uuid_link)) { } else if (!qemu_uuid_is_null(&uuid_link)) {
error_setg(errp, "unsupported VDI image (non-NULL link UUID)"); error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (!qemu_uuid_is_null(&header.uuid_parent)) { } else if (!qemu_uuid_is_null(&uuid_parent)) {
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)"); error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
@ -733,6 +742,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
BlockDriverState *bs_file = NULL; BlockDriverState *bs_file = NULL;
BlockBackend *blk = NULL; BlockBackend *blk = NULL;
uint32_t *bmap = NULL; uint32_t *bmap = NULL;
QemuUUID uuid;
assert(create_options->driver == BLOCKDEV_DRIVER_VDI); assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
vdi_opts = &create_options->u.vdi; vdi_opts = &create_options->u.vdi;
@ -819,8 +829,10 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
if (image_type == VDI_TYPE_STATIC) { if (image_type == VDI_TYPE_STATIC) {
header.blocks_allocated = blocks; header.blocks_allocated = blocks;
} }
qemu_uuid_generate(&header.uuid_image); qemu_uuid_generate(&uuid);
qemu_uuid_generate(&header.uuid_last_snap); header.uuid_image = uuid;
qemu_uuid_generate(&uuid);
header.uuid_last_snap = uuid;
/* There is no need to set header.uuid_link or header.uuid_parent here. */ /* There is no need to set header.uuid_link or header.uuid_parent here. */
if (VDI_DEBUG) { if (VDI_DEBUG) {
vdi_header_print(&header); vdi_header_print(&header);