From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: eblake@redhat.com, vsementsov@virtuozzo.com,
Kevin Wolf <kwolf@redhat.com>,
qemu-block@nongnu.org, Max Reitz <mreitz@redhat.com>,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH 1/5] block/qcow2-bitmap: Skip length check in some cases
Date: Tue, 5 Mar 2019 18:43:33 -0500 [thread overview]
Message-ID: <20190305234337.18353-2-jsnow@redhat.com> (raw)
In-Reply-To: <20190305234337.18353-1-jsnow@redhat.com>
If we were to allow resizes, the length check that happens when we load
bitmap headers from disk when we read or store bitmaps would begin to
fail:
Imagine the circumstance where we've resized bitmaps in memory, but they still
have the old values on-disk. The lengths will no longer match bdrv_getlength,
so we must allow this check to be skipped when flushing bitmaps to disk.
Limit this to when we are about to overwrite the headers: we will verify the
outgoing headers, but we will skip verifying the known stale headers.
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/qcow2-bitmap.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index c3b210ede1..d02730004a 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -435,7 +435,8 @@ static inline Qcow2BitmapDirEntry *next_dir_entry(Qcow2BitmapDirEntry *entry)
return (Qcow2BitmapDirEntry *)((uint8_t *)entry + dir_entry_size(entry));
}
-static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry)
+static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry,
+ bool allow_resize)
{
BDRVQcow2State *s = bs->opaque;
uint64_t phys_bitmap_bytes;
@@ -462,8 +463,14 @@ static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry)
return len;
}
- fail = (phys_bitmap_bytes > BME_MAX_PHYS_SIZE) ||
- (len > ((phys_bitmap_bytes * 8) << entry->granularity_bits));
+ if (phys_bitmap_bytes > BME_MAX_PHYS_SIZE) {
+ return -EINVAL;
+ }
+
+ if (!allow_resize &&
+ (len > ((phys_bitmap_bytes * 8) << entry->granularity_bits))) {
+ return -EINVAL;
+ }
return fail ? -EINVAL : 0;
}
@@ -534,7 +541,8 @@ static uint32_t bitmap_list_count(Qcow2BitmapList *bm_list)
* checks it and convert to bitmap list.
*/
static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
- uint64_t size, Error **errp)
+ uint64_t size, bool allow_resize,
+ Error **errp)
{
int ret;
BDRVQcow2State *s = bs->opaque;
@@ -593,7 +601,7 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
goto fail;
}
- ret = check_dir_entry(bs, e);
+ ret = check_dir_entry(bs, e, allow_resize);
if (ret < 0) {
error_setg(errp, "Bitmap '%.*s' doesn't satisfy the constraints",
e->name_size, dir_entry_name_field(e));
@@ -654,7 +662,7 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, NULL);
+ s->bitmap_directory_size, false, NULL);
if (bm_list == NULL) {
res->corruptions++;
return -EINVAL;
@@ -755,7 +763,7 @@ static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
e->extra_data_size = 0;
memcpy(e + 1, bm->name, e->name_size);
- if (check_dir_entry(bs, e) < 0) {
+ if (check_dir_entry(bs, e, false) < 0) {
ret = -EINVAL;
goto fail;
}
@@ -957,7 +965,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp)
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, false, errp);
if (bm_list == NULL) {
return false;
}
@@ -1066,7 +1074,7 @@ Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs,
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, false, errp);
if (bm_list == NULL) {
return NULL;
}
@@ -1111,7 +1119,7 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, false, errp);
if (bm_list == NULL) {
return -EINVAL;
}
@@ -1359,7 +1367,7 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, false, errp);
if (bm_list == NULL) {
return;
}
@@ -1412,7 +1420,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
bm_list = bitmap_list_new();
} else {
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, true, errp);
if (bm_list == NULL) {
return;
}
@@ -1593,7 +1601,7 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
}
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ s->bitmap_directory_size, false, errp);
if (bm_list == NULL) {
goto fail;
}
--
2.17.2
next prev parent reply other threads:[~2019-03-05 23:43 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-05 23:43 [Qemu-devel] [PATCH 0/5] block/qcow2-bitmap: Enable resize with persistent bitmaps John Snow
2019-03-05 23:43 ` John Snow [this message]
2019-03-06 12:34 ` [Qemu-devel] [PATCH 1/5] block/qcow2-bitmap: Skip length check in some cases Eric Blake
2019-03-06 15:21 ` Vladimir Sementsov-Ogievskiy
2019-03-06 15:35 ` John Snow
2019-03-06 16:07 ` Vladimir Sementsov-Ogievskiy
2019-03-08 22:10 ` John Snow
2019-03-05 23:43 ` [Qemu-devel] [PATCH 2/5] block/qcow2-bitmap: Allow bitmap flushing John Snow
2019-03-06 12:58 ` Eric Blake
2019-03-06 15:59 ` John Snow
2019-03-06 16:12 ` Vladimir Sementsov-Ogievskiy
2019-03-08 22:11 ` John Snow
2019-03-05 23:43 ` [Qemu-devel] [PATCH 3/5] block/qcow2-bitmap: don't remove bitmaps on reopen John Snow
2019-03-06 15:28 ` Vladimir Sementsov-Ogievskiy
2019-03-06 15:38 ` John Snow
2019-03-05 23:43 ` [Qemu-devel] [PATCH 4/5] block/qcow2-bitmap: Allow resizes with persistent bitmaps John Snow
2019-03-06 15:33 ` Vladimir Sementsov-Ogievskiy
2019-03-06 15:36 ` Eric Blake
2019-03-06 15:44 ` Vladimir Sementsov-Ogievskiy
2019-03-06 15:41 ` John Snow
2019-03-06 15:52 ` Vladimir Sementsov-Ogievskiy
2019-03-06 15:56 ` Vladimir Sementsov-Ogievskiy
2019-03-09 0:35 ` John Snow
2019-03-05 23:43 ` [Qemu-devel] [PATCH 5/5] tests/qemu-iotests: add bitmap resize test 246 John Snow
2019-03-06 0:02 ` [Qemu-devel] [PATCH 0/5] block/qcow2-bitmap: Enable resize with persistent bitmaps John Snow
2019-03-10 16:50 ` no-reply
2019-03-11 16:18 ` Eric Blake
2019-03-11 17:36 ` Vladimir Sementsov-Ogievskiy
2019-03-11 17:48 ` Eric Blake
2019-03-11 18:05 ` Vladimir Sementsov-Ogievskiy
2019-03-11 18:05 ` John Snow
2019-03-11 18:26 ` Vladimir Sementsov-Ogievskiy
2019-03-11 18:35 ` John Snow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190305234337.18353-2-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).