qemu/block
Daniel P. Berrangé 087ab8e775 block: always fill entire LUKS header space with zeros
When initializing the LUKS header the size with default encryption
parameters will currently be 2068480 bytes. This is rounded up to
a multiple of the cluster size, 2081792, with 64k sectors. If the
end of the header is not the same as the end of the cluster we fill
the extra space with zeros. This was forgetting that not even the
space allocated for the header will be fully initialized, as we
only write key material for the first key slot. The space left
for the other 7 slots is never written to.

An optimization to the ref count checking code:

  commit a5fff8d4b4 (refs/bisect/bad)
  Author: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
  Date:   Wed Feb 27 16:14:30 2019 +0300

    qcow2-refcount: avoid eating RAM

made the assumption that every cluster which was allocated would
have at least some data written to it. This was violated by way
the LUKS header is only partially written, with much space simply
reserved for future use.

Depending on the cluster size this problem was masked by the
logic which wrote zeros between the end of the LUKS header and
the end of the cluster.

$ qemu-img create --object secret,id=cluster_encrypt0,data=123456 \
   -f qcow2 -o cluster_size=2k,encrypt.iter-time=1,\
               encrypt.format=luks,encrypt.key-secret=cluster_encrypt0 \
               cluster_size_check.qcow2 100M
  Formatting 'cluster_size_check.qcow2', fmt=qcow2 size=104857600
    encrypt.format=luks encrypt.key-secret=cluster_encrypt0
    encrypt.iter-time=1 cluster_size=2048 lazy_refcounts=off refcount_bits=16

$ qemu-img check --object secret,id=cluster_encrypt0,data=redhat \
    'json:{"driver": "qcow2", "encrypt.format": "luks", \
           "encrypt.key-secret": "cluster_encrypt0", \
           "file.driver": "file", "file.filename": "cluster_size_check.qcow2"}'
ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x2000 size 0x1f9000
Leaked cluster 4 refcount=1 reference=0
...snip...
Leaked cluster 130 refcount=1 reference=0

1 errors were found on the image.
Data may be corrupted, or further writes to the image may corrupt it.

127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
Image end offset: 268288

The problem only exists when the disk image is entirely empty. Writing
data to the disk image payload will solve the problem by causing the
end of the file to be extended further.

The change fixes it by ensuring that the entire allocated LUKS header
region is fully initialized with zeros. The qemu-img check will still
fail for any pre-existing disk images created prior to this change,
unless at least 1 byte of the payload is written to.

Fully writing zeros to the entire LUKS header is a good idea regardless
as it ensures that space has been allocated on the host filesystem (or
whatever block storage backend is used).

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20200207135520.2669430-1-berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2020-02-20 16:43:42 +01:00
..
accounting.c block: add empty account cookie type 2019-10-10 10:56:18 +02:00
aio_task.c block: introduce aio task pool 2019-10-10 10:56:17 +02:00
backup-top.c block/backup-top: fix failure path 2020-02-06 13:47:45 +01:00
backup-top.h block: introduce backup-top filter driver 2019-10-10 10:56:18 +02:00
backup.c block/backup-top: Don't acquire context while dropping top 2020-01-27 17:19:53 +01:00
blkdebug.c blkdebug: Allow taking/unsharing permissions 2020-01-06 13:43:06 +01:00
blklogwrites.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
blkreplay.c block: implement bdrv_snapshot_goto for blkreplay 2019-10-14 17:12:48 +02:00
blkverify.c block: Remove bdrv_recurse_is_first_non_filter() 2020-02-18 11:55:40 +01:00
block-backend.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
block-copy.c block/block-copy: fix s->copy_size for compressed cluster 2019-11-04 09:21:45 +01:00
bochs.c block: Use QEMU_IS_ALIGNED 2019-09-16 14:48:30 +02:00
cloop.c block: Use QEMU_IS_ALIGNED 2019-09-16 14:48:30 +02:00
commit.c commit: Fix is_read for block_job_error_action() 2020-02-18 10:53:56 +01:00
copy-on-read.c block: Remove bdrv_recurse_is_first_non_filter() 2020-02-18 11:55:40 +01:00
create.c block/create: Do not abort if a block driver is not available 2019-09-13 12:18:37 +02:00
crypto.c block: Let format drivers pass @exact 2019-10-28 12:05:30 +01:00
crypto.h Clean up ill-advised or unusual header guards 2019-05-13 08:58:55 +02:00
curl.c curl: Check curl_multi_add_handle()'s return code 2019-09-16 15:31:12 +02:00
dirty-bitmap.c bitmap: Enforce maximum bitmap name length 2019-11-18 16:01:34 -06:00
dmg-bz2.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-lzfse.c block: adding lzfse decompressing support as a module. 2018-12-14 11:52:40 +01:00
dmg.c block: Use QEMU_IS_ALIGNED 2019-09-16 14:48:30 +02:00
dmg.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
file-posix.c block/file-posix.c: extend to use io_uring 2020-01-30 20:59:42 +00:00
file-win32.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
filter-compress.c block: Remove bdrv_recurse_is_first_non_filter() 2020-02-18 11:55:40 +01:00
gluster.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
io_uring.c block/io_uring: Remove superfluous semicolon 2020-02-18 10:54:02 +01:00
io.c block: fix crash on zero-length unaligned write and read 2020-02-07 16:46:59 +00:00
iscsi-opts.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
iscsi.c iscsi: Don't access non-existent scsi_lba_status_descriptor 2020-01-27 17:19:53 +01:00
linux-aio.c linux-aio: increasing MAX_EVENTS to a larger hardcoded value 2020-01-13 16:41:45 +00:00
Makefile.objs block/io_uring: implements interfaces for io_uring 2020-01-30 20:59:41 +00:00
mirror.c mirror: Double-check immediately before replacing 2020-02-18 11:55:40 +01:00
nbd.c nbd: assert that Error** is not NULL in nbd_iter_channel_error 2019-12-18 08:43:19 +01:00
nfs.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
null.c replay: add BH oneshot event for block layer 2019-10-14 17:12:48 +02:00
nvme.c block/nvme: add support for discard 2019-10-28 11:34:35 +01:00
parallels.c Block patches for softfreeze: 2019-10-28 14:40:01 +00:00
parallels.h Clean up includes 2018-02-09 05:05:11 +01:00
qapi.c qapi: Allow getting flat output from 'query-named-block-nodes' 2020-02-20 16:43:42 +01:00
qcow2-bitmap.c block/qcow2-bitmap: Remove unneeded variable assignment 2020-02-18 10:53:56 +01:00
qcow2-cache.c core: replace getpagesize() with qemu_real_host_page_size 2019-10-26 15:38:06 +02:00
qcow2-cluster.c qcow2: Fix qcow2_alloc_cluster_abort() for external data file 2020-02-18 10:53:56 +01:00
qcow2-refcount.c qcow2: update_refcount(): Reset old_table_index after qcow2_cache_put() 2020-02-18 10:53:56 +01:00
qcow2-snapshot.c qcow2: Don't round the L1 table allocation up to the sector size 2020-02-06 13:47:45 +01:00
qcow2-threads.c qcow2: Fix alignment checks in encrypted images 2020-02-18 10:53:56 +01:00
qcow2.c block: always fill entire LUKS header space with zeros 2020-02-20 16:43:42 +01:00
qcow2.h qcow2: Fix QCOW2_COMPRESSED_SECTOR_MASK 2019-11-07 14:37:46 +01:00
qcow.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
qed-check.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed-cluster.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-l2-cache.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-table.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed.c block: Pass truncate exact=true where reasonable 2019-10-28 12:08:45 +01:00
qed.h block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
quorum.c quorum: Stop marking it as a filter 2020-02-18 11:55:40 +01:00
raw-format.c block: Let format drivers pass @exact 2019-10-28 12:05:30 +01:00
rbd.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
replication.c block: Remove bdrv_recurse_is_first_non_filter() 2020-02-18 11:55:40 +01:00
sheepdog.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
snapshot.c block/snapshot: rename Error ** parameter to more common errp 2019-12-18 08:43:19 +01:00
ssh.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
stream.c job: drop job_drain 2019-09-10 08:58:43 +02:00
throttle-groups.c throttle-groups: fix memory leak in throttle_group_set_limit: 2020-01-06 13:43:06 +01:00
throttle.c block: Remove bdrv_recurse_is_first_non_filter() 2020-02-18 11:55:40 +01:00
trace-events block: add trace events for io_uring 2020-01-30 20:59:42 +00:00
vdi.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
vhdx-endian.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
vhdx-log.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
vhdx.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
vhdx.h block/vhdx: Use IEC binary prefixes for size constants 2019-04-30 15:29:00 +02:00
vmdk.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
vpc.c block: Add @exact parameter to bdrv_co_truncate() 2019-10-28 12:00:07 +01:00
vvfat.c block/vvfat: Do not unref qcow on closing backing bdrv 2020-02-18 10:53:56 +01:00
vxhs.c replay: add BH oneshot event for block layer 2019-10-14 17:12:48 +02:00
win32-aio.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
write-threshold.c qapi: Drop qapi_event_send_FOO()'s Error ** argument 2018-08-28 18:21:38 +02:00