diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-10-09 18:24:59 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-11-05 15:09:54 +0100 |
commit | 3b698f52f9fabb4fb7844f57160c65cd6ce6513c (patch) | |
tree | 13900feeb99ce628b1188f6778e11dc4d41cf2e0 /block/qcow2.c | |
parent | cf67b692b38a5e0a76d6d94f77fd4aa1b5d31849 (diff) |
block/qcow2: 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. Avoid the bug by not using the
"modify in place" byte swapping functions.
There are a few places where the in-place swap function is
used on something other than a packed struct field; we convert
those anyway, for consistency.
This patch was produced with the following spatch script
(and hand-editing to fold a few resulting overlength lines):
@@
expression E;
@@
-be16_to_cpus(&E);
+E = be16_to_cpu(E);
@@
expression E;
@@
-be32_to_cpus(&E);
+E = be32_to_cpu(E);
@@
expression E;
@@
-be64_to_cpus(&E);
+E = be64_to_cpu(E);
@@
expression E;
@@
-cpu_to_be16s(&E);
+E = cpu_to_be16(E);
@@
expression E;
@@
-cpu_to_be32s(&E);
+E = cpu_to_be32(E);
@@
expression E;
@@
-cpu_to_be64s(&E);
+E = cpu_to_be64(E);
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: John Snow <jsnow@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2.c')
-rw-r--r-- | block/qcow2.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/block/qcow2.c b/block/qcow2.c index 30689b7688..de94b290e6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -210,8 +210,8 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, "pread fail from offset %" PRIu64, offset); return 1; } - be32_to_cpus(&ext.magic); - be32_to_cpus(&ext.len); + ext.magic = be32_to_cpu(ext.magic); + ext.len = be32_to_cpu(ext.len); offset += sizeof(ext); #ifdef DEBUG_EXT printf("ext.magic = 0x%x\n", ext.magic); @@ -279,8 +279,8 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, "Unable to read CRYPTO header extension"); return ret; } - be64_to_cpus(&s->crypto_header.offset); - be64_to_cpus(&s->crypto_header.length); + s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset); + s->crypto_header.length = be64_to_cpu(s->crypto_header.length); if ((s->crypto_header.offset % s->cluster_size) != 0) { error_setg(errp, "Encryption header offset '%" PRIu64 "' is " @@ -342,9 +342,11 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, return -EINVAL; } - be32_to_cpus(&bitmaps_ext.nb_bitmaps); - be64_to_cpus(&bitmaps_ext.bitmap_directory_size); - be64_to_cpus(&bitmaps_ext.bitmap_directory_offset); + bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps); + bitmaps_ext.bitmap_directory_size = + be64_to_cpu(bitmaps_ext.bitmap_directory_size); + bitmaps_ext.bitmap_directory_offset = + be64_to_cpu(bitmaps_ext.bitmap_directory_offset); if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) { error_setg(errp, @@ -1159,19 +1161,20 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, error_setg_errno(errp, -ret, "Could not read qcow2 header"); goto fail; } - be32_to_cpus(&header.magic); - be32_to_cpus(&header.version); - be64_to_cpus(&header.backing_file_offset); - be32_to_cpus(&header.backing_file_size); - be64_to_cpus(&header.size); - be32_to_cpus(&header.cluster_bits); - be32_to_cpus(&header.crypt_method); - be64_to_cpus(&header.l1_table_offset); - be32_to_cpus(&header.l1_size); - be64_to_cpus(&header.refcount_table_offset); - be32_to_cpus(&header.refcount_table_clusters); - be64_to_cpus(&header.snapshots_offset); - be32_to_cpus(&header.nb_snapshots); + header.magic = be32_to_cpu(header.magic); + header.version = be32_to_cpu(header.version); + header.backing_file_offset = be64_to_cpu(header.backing_file_offset); + header.backing_file_size = be32_to_cpu(header.backing_file_size); + header.size = be64_to_cpu(header.size); + header.cluster_bits = be32_to_cpu(header.cluster_bits); + header.crypt_method = be32_to_cpu(header.crypt_method); + header.l1_table_offset = be64_to_cpu(header.l1_table_offset); + header.l1_size = be32_to_cpu(header.l1_size); + header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset); + header.refcount_table_clusters = + be32_to_cpu(header.refcount_table_clusters); + header.snapshots_offset = be64_to_cpu(header.snapshots_offset); + header.nb_snapshots = be32_to_cpu(header.nb_snapshots); if (header.magic != QCOW_MAGIC) { error_setg(errp, "Image is not in qcow2 format"); @@ -1207,11 +1210,12 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, header.refcount_order = 4; header.header_length = 72; } else { - be64_to_cpus(&header.incompatible_features); - be64_to_cpus(&header.compatible_features); - be64_to_cpus(&header.autoclear_features); - be32_to_cpus(&header.refcount_order); - be32_to_cpus(&header.header_length); + header.incompatible_features = + be64_to_cpu(header.incompatible_features); + header.compatible_features = be64_to_cpu(header.compatible_features); + header.autoclear_features = be64_to_cpu(header.autoclear_features); + header.refcount_order = be32_to_cpu(header.refcount_order); + header.header_length = be32_to_cpu(header.header_length); if (header.header_length < 104) { error_setg(errp, "qcow2 header too short"); @@ -1400,7 +1404,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, goto fail; } for(i = 0;i < s->l1_size; i++) { - be64_to_cpus(&s->l1_table[i]); + s->l1_table[i] = be64_to_cpu(s->l1_table[i]); } } @@ -2392,13 +2396,13 @@ int qcow2_update_header(BlockDriverState *bs) /* Full disk encryption header pointer extension */ if (s->crypto_header.offset != 0) { - cpu_to_be64s(&s->crypto_header.offset); - cpu_to_be64s(&s->crypto_header.length); + s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset); + s->crypto_header.length = cpu_to_be64(s->crypto_header.length); ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER, &s->crypto_header, sizeof(s->crypto_header), buflen); - be64_to_cpus(&s->crypto_header.offset); - be64_to_cpus(&s->crypto_header.length); + s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset); + s->crypto_header.length = be64_to_cpu(s->crypto_header.length); if (ret < 0) { goto fail; } |