From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9d9-000215-0V for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:10:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zw9d5-0004JA-4v for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:10:38 -0500 From: Kevin Wolf Date: Tue, 10 Nov 2015 15:09:24 +0100 Message-Id: <1447164580-31094-25-git-send-email-kwolf@redhat.com> In-Reply-To: <1447164580-31094-1-git-send-email-kwolf@redhat.com> References: <1447164580-31094-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PULL v2 24/40] qcow2: avoid misaligned 64bit bswap List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: John Snow If we create a buffer directly on the stack by using 12 bytes, there's no guarantee the 64bit value we want to swap will be aligned, which could cause errors with undefined behavior. Spotted with clang -fsanitize=undefined and observed in iotests 15, 26, 44, 115 and 121. Signed-off-by: John Snow Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- block/qcow2-refcount.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 4b81c8d..6e0e5bd 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -560,13 +560,16 @@ static int alloc_refcount_block(BlockDriverState *bs, } /* Hook up the new refcount table in the qcow2 header */ - uint8_t data[12]; - cpu_to_be64w((uint64_t*)data, table_offset); - cpu_to_be32w((uint32_t*)(data + 8), table_clusters); + struct QEMU_PACKED { + uint64_t d64; + uint32_t d32; + } data; + cpu_to_be64w(&data.d64, table_offset); + cpu_to_be32w(&data.d32, table_clusters); BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE); ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, refcount_table_offset), - data, sizeof(data)); + &data, sizeof(data)); if (ret < 0) { goto fail_table; } -- 1.8.3.1