* [Qemu-devel] [PATCH 0/2] VHDX cleanup @ 2017-08-07 3:08 Jeff Cody 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Jeff Cody @ 2017-08-07 3:08 UTC (permalink / raw) To: qemu-devel; +Cc: qemu-block, armbru Two VHDX items cleaned up: 1. Check for error when calling bdrv_getlength() [Markus] 2. Check for overflow in offset prior to calling bdrv_truncate(). Jeff Cody (2): block/vhdx: check error return of bdrv_getlength() block/vhdx: check for offset overflow to bdrv_truncate() block/vhdx-log.c | 24 ++++++++++++++++++++---- block/vhdx.c | 12 +++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) -- 2.9.4 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() 2017-08-07 3:08 [Qemu-devel] [PATCH 0/2] VHDX cleanup Jeff Cody @ 2017-08-07 3:08 ` Jeff Cody 2017-08-07 10:46 ` [Qemu-devel] [Qemu-block] " Kevin Wolf 2017-08-07 11:25 ` [Qemu-devel] " Eric Blake 2017-08-07 3:08 ` [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() Jeff Cody 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] [PATCH 0/2] VHDX cleanup Kevin Wolf 2 siblings, 2 replies; 10+ messages in thread From: Jeff Cody @ 2017-08-07 3:08 UTC (permalink / raw) To: qemu-devel; +Cc: qemu-block, armbru Calls to bdrv_getlength() were not checking for error. In vhdx.c, this can lead to truncating an image file, so it is a definite bug. In vhdx-log.c, the path for improper behavior is less clear, but it is best to check in any case. Reported-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Jeff Cody <jcody@redhat.com> --- block/vhdx-log.c | 20 ++++++++++++++++---- block/vhdx.c | 9 ++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/block/vhdx-log.c b/block/vhdx-log.c index 01278f3..fd4e7af 100644 --- a/block/vhdx-log.c +++ b/block/vhdx-log.c @@ -491,6 +491,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, uint32_t cnt, sectors_read; uint64_t new_file_size; void *data = NULL; + int64_t file_length; VHDXLogDescEntries *desc_entries = NULL; VHDXLogEntryHeader hdr_tmp = { 0 }; @@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, if (ret < 0) { goto exit; } + file_length = bdrv_getlength(bs->file->bs); + if (file_length < 0) { + ret = file_length; + goto exit; + } /* if the log shows a FlushedFileOffset larger than our current file * size, then that means the file has been truncated / corrupted, and * we must refused to open it / use it */ - if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) { + if (hdr_tmp.flushed_file_offset > file_length) { ret = -EINVAL; goto exit; } @@ -543,7 +549,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, goto exit; } } - if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) { + if (file_length < desc_entries->hdr.last_file_offset) { new_file_size = desc_entries->hdr.last_file_offset; if (new_file_size % (1024*1024)) { /* round up to nearest 1MB boundary */ @@ -851,6 +857,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, uint32_t partial_sectors = 0; uint32_t bytes_written = 0; uint64_t file_offset; + int64_t file_length; VHDXHeader *header; VHDXLogEntryHeader new_hdr; VHDXLogDescriptor *new_desc = NULL; @@ -913,10 +920,15 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, .sequence_number = s->log.sequence, .descriptor_count = sectors, .reserved = 0, - .flushed_file_offset = bdrv_getlength(bs->file->bs), - .last_file_offset = bdrv_getlength(bs->file->bs), }; + file_length = bdrv_getlength(bs->file->bs); + if (file_length < 0) { + ret = file_length; + goto exit; + } + new_hdr.flushed_file_offset = file_length; + new_hdr.last_file_offset = file_length; new_hdr.log_guid = header->log_guid; desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count); diff --git a/block/vhdx.c b/block/vhdx.c index a9cecd2..6a14999 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1166,7 +1166,14 @@ exit: static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, uint64_t *new_offset) { - *new_offset = bdrv_getlength(bs->file->bs); + int64_t current_len; + current_len = bdrv_getlength(bs->file->bs); + + if (current_len < 0) { + return current_len; + } + + *new_offset = current_len; /* per the spec, the address for a block is in units of 1MB */ *new_offset = ROUND_UP(*new_offset, 1024 * 1024); -- 2.9.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody @ 2017-08-07 10:46 ` Kevin Wolf 2017-08-07 12:16 ` Jeff Cody 2017-08-07 11:25 ` [Qemu-devel] " Eric Blake 1 sibling, 1 reply; 10+ messages in thread From: Kevin Wolf @ 2017-08-07 10:46 UTC (permalink / raw) To: Jeff Cody; +Cc: qemu-devel, armbru, qemu-block Am 07.08.2017 um 05:08 hat Jeff Cody geschrieben: > Calls to bdrv_getlength() were not checking for error. In vhdx.c, this > can lead to truncating an image file, so it is a definite bug. In > vhdx-log.c, the path for improper behavior is less clear, but it is best > to check in any case. > > Reported-by: Markus Armbruster <armbru@redhat.com> > Signed-off-by: Jeff Cody <jcody@redhat.com> > --- > block/vhdx-log.c | 20 ++++++++++++++++---- > block/vhdx.c | 9 ++++++++- > 2 files changed, 24 insertions(+), 5 deletions(-) > > diff --git a/block/vhdx-log.c b/block/vhdx-log.c > index 01278f3..fd4e7af 100644 > --- a/block/vhdx-log.c > +++ b/block/vhdx-log.c > @@ -491,6 +491,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > uint32_t cnt, sectors_read; > uint64_t new_file_size; > void *data = NULL; > + int64_t file_length; > VHDXLogDescEntries *desc_entries = NULL; > VHDXLogEntryHeader hdr_tmp = { 0 }; > > @@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > if (ret < 0) { > goto exit; > } > + file_length = bdrv_getlength(bs->file->bs); > + if (file_length < 0) { > + ret = file_length; > + goto exit; > + } > /* if the log shows a FlushedFileOffset larger than our current file > * size, then that means the file has been truncated / corrupted, and > * we must refused to open it / use it */ > - if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) { > + if (hdr_tmp.flushed_file_offset > file_length) { > ret = -EINVAL; > goto exit; > } > @@ -543,7 +549,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > goto exit; > } > } > - if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) { > + if (file_length < desc_entries->hdr.last_file_offset) { > new_file_size = desc_entries->hdr.last_file_offset; > if (new_file_size % (1024*1024)) { > /* round up to nearest 1MB boundary */ The vhdx_log_flush() part looks good, but it made me notice a bdrv_flush() in the same function where the return value isn't checked. I'm almost sure that this is a bug. > @@ -851,6 +857,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, > uint32_t partial_sectors = 0; > uint32_t bytes_written = 0; > uint64_t file_offset; > + int64_t file_length; > VHDXHeader *header; > VHDXLogEntryHeader new_hdr; > VHDXLogDescriptor *new_desc = NULL; > @@ -913,10 +920,15 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, > .sequence_number = s->log.sequence, > .descriptor_count = sectors, > .reserved = 0, > - .flushed_file_offset = bdrv_getlength(bs->file->bs), > - .last_file_offset = bdrv_getlength(bs->file->bs), > }; > > + file_length = bdrv_getlength(bs->file->bs); > + if (file_length < 0) { > + ret = file_length; > + goto exit; > + } > + new_hdr.flushed_file_offset = file_length; > + new_hdr.last_file_offset = file_length; > new_hdr.log_guid = header->log_guid; If you move the bdrv_getlength() above the initialisation of new_hdr, you could keep these fields in the designated initialiser, which should be better for readability. I also don't know why .log_guid isn't part if it, could be moved, too. > desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count); > diff --git a/block/vhdx.c b/block/vhdx.c > index a9cecd2..6a14999 100644 > --- a/block/vhdx.c > +++ b/block/vhdx.c > @@ -1166,7 +1166,14 @@ exit: > static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, > uint64_t *new_offset) > { > - *new_offset = bdrv_getlength(bs->file->bs); > + int64_t current_len; > + current_len = bdrv_getlength(bs->file->bs); > + > + if (current_len < 0) { > + return current_len; > + } Don't you want the empty line to be between declaration and code rather than assignment and check? > + *new_offset = current_len; > > /* per the spec, the address for a block is in units of 1MB */ > *new_offset = ROUND_UP(*new_offset, 1024 * 1024); So the code looks correct, but we could make it a little nicer in a v2. Kevin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() 2017-08-07 10:46 ` [Qemu-devel] [Qemu-block] " Kevin Wolf @ 2017-08-07 12:16 ` Jeff Cody 0 siblings, 0 replies; 10+ messages in thread From: Jeff Cody @ 2017-08-07 12:16 UTC (permalink / raw) To: Kevin Wolf; +Cc: qemu-devel, armbru, qemu-block On Mon, Aug 07, 2017 at 12:46:30PM +0200, Kevin Wolf wrote: > Am 07.08.2017 um 05:08 hat Jeff Cody geschrieben: > > Calls to bdrv_getlength() were not checking for error. In vhdx.c, this > > can lead to truncating an image file, so it is a definite bug. In > > vhdx-log.c, the path for improper behavior is less clear, but it is best > > to check in any case. > > > > Reported-by: Markus Armbruster <armbru@redhat.com> > > Signed-off-by: Jeff Cody <jcody@redhat.com> > > --- > > block/vhdx-log.c | 20 ++++++++++++++++---- > > block/vhdx.c | 9 ++++++++- > > 2 files changed, 24 insertions(+), 5 deletions(-) > > > > diff --git a/block/vhdx-log.c b/block/vhdx-log.c > > index 01278f3..fd4e7af 100644 > > --- a/block/vhdx-log.c > > +++ b/block/vhdx-log.c > > @@ -491,6 +491,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > > uint32_t cnt, sectors_read; > > uint64_t new_file_size; > > void *data = NULL; > > + int64_t file_length; > > VHDXLogDescEntries *desc_entries = NULL; > > VHDXLogEntryHeader hdr_tmp = { 0 }; > > > > @@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > > if (ret < 0) { > > goto exit; > > } > > + file_length = bdrv_getlength(bs->file->bs); > > + if (file_length < 0) { > > + ret = file_length; > > + goto exit; > > + } > > /* if the log shows a FlushedFileOffset larger than our current file > > * size, then that means the file has been truncated / corrupted, and > > * we must refused to open it / use it */ > > - if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) { > > + if (hdr_tmp.flushed_file_offset > file_length) { > > ret = -EINVAL; > > goto exit; > > } > > @@ -543,7 +549,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > > goto exit; > > } > > } > > - if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) { > > + if (file_length < desc_entries->hdr.last_file_offset) { > > new_file_size = desc_entries->hdr.last_file_offset; > > if (new_file_size % (1024*1024)) { > > /* round up to nearest 1MB boundary */ > > The vhdx_log_flush() part looks good, but it made me notice a > bdrv_flush() in the same function where the return value isn't checked. > I'm almost sure that this is a bug. > I'll add 2 more simple patches to the series: one for bdrv_flush(), and one for the unchecked bdrv_truncate() as well. > > @@ -851,6 +857,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, > > uint32_t partial_sectors = 0; > > uint32_t bytes_written = 0; > > uint64_t file_offset; > > + int64_t file_length; > > VHDXHeader *header; > > VHDXLogEntryHeader new_hdr; > > VHDXLogDescriptor *new_desc = NULL; > > @@ -913,10 +920,15 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, > > .sequence_number = s->log.sequence, > > .descriptor_count = sectors, > > .reserved = 0, > > - .flushed_file_offset = bdrv_getlength(bs->file->bs), > > - .last_file_offset = bdrv_getlength(bs->file->bs), > > }; > > > > + file_length = bdrv_getlength(bs->file->bs); > > + if (file_length < 0) { > > + ret = file_length; > > + goto exit; > > + } > > + new_hdr.flushed_file_offset = file_length; > > + new_hdr.last_file_offset = file_length; > > new_hdr.log_guid = header->log_guid; > > If you move the bdrv_getlength() above the initialisation of new_hdr, > you could keep these fields in the designated initialiser, which should > be better for readability. > > I also don't know why .log_guid isn't part if it, could be moved, too. > > > desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count); > > diff --git a/block/vhdx.c b/block/vhdx.c > > index a9cecd2..6a14999 100644 > > --- a/block/vhdx.c > > +++ b/block/vhdx.c > > @@ -1166,7 +1166,14 @@ exit: > > static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, > > uint64_t *new_offset) > > { > > - *new_offset = bdrv_getlength(bs->file->bs); > > + int64_t current_len; > > + current_len = bdrv_getlength(bs->file->bs); > > + > > + if (current_len < 0) { > > + return current_len; > > + } > > Don't you want the empty line to be between declaration and code rather > than assignment and check? > > > + *new_offset = current_len; > > > > /* per the spec, the address for a block is in units of 1MB */ > > *new_offset = ROUND_UP(*new_offset, 1024 * 1024); > > So the code looks correct, but we could make it a little nicer in a v2. > Yep, thanks. I'll address all those cleanups you mentioned in v2. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody 2017-08-07 10:46 ` [Qemu-devel] [Qemu-block] " Kevin Wolf @ 2017-08-07 11:25 ` Eric Blake 1 sibling, 0 replies; 10+ messages in thread From: Eric Blake @ 2017-08-07 11:25 UTC (permalink / raw) To: Jeff Cody, qemu-devel; +Cc: armbru, qemu-block [-- Attachment #1: Type: text/plain, Size: 716 bytes --] On 08/06/2017 10:08 PM, Jeff Cody wrote: > Calls to bdrv_getlength() were not checking for error. In vhdx.c, this > can lead to truncating an image file, so it is a definite bug. In > vhdx-log.c, the path for improper behavior is less clear, but it is best > to check in any case. > > Reported-by: Markus Armbruster <armbru@redhat.com> > Signed-off-by: Jeff Cody <jcody@redhat.com> > --- > block/vhdx-log.c | 20 ++++++++++++++++---- > block/vhdx.c | 9 ++++++++- > 2 files changed, 24 insertions(+), 5 deletions(-) Reviewed-by: Eric Blake <eblake@redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 619 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() 2017-08-07 3:08 [Qemu-devel] [PATCH 0/2] VHDX cleanup Jeff Cody 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody @ 2017-08-07 3:08 ` Jeff Cody 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] " Kevin Wolf 2017-08-07 11:24 ` [Qemu-devel] " Eric Blake 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] [PATCH 0/2] VHDX cleanup Kevin Wolf 2 siblings, 2 replies; 10+ messages in thread From: Jeff Cody @ 2017-08-07 3:08 UTC (permalink / raw) To: qemu-devel; +Cc: qemu-block, armbru VHDX uses uint64_t types for most offsets, following the VHDX spec. However, bdrv_truncate() takes an int64_t value for the truncating offset. Check for overflow before calling bdrv_truncate(). N.B.: For a compliant image this is not an issue, as the maximum VHDX image size is defined per the spec to be 64TB. Signed-off-by: Jeff Cody <jcody@redhat.com> --- block/vhdx-log.c | 4 ++++ block/vhdx.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/block/vhdx-log.c b/block/vhdx-log.c index fd4e7af..3b74e5d 100644 --- a/block/vhdx-log.c +++ b/block/vhdx-log.c @@ -554,6 +554,10 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, if (new_file_size % (1024*1024)) { /* round up to nearest 1MB boundary */ new_file_size = ((new_file_size >> 20) + 1) << 20; + if (new_file_size > INT64_MAX) { + ret = -EINVAL; + goto exit; + } bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); } } diff --git a/block/vhdx.c b/block/vhdx.c index 6a14999..c45af73 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1177,6 +1177,9 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, /* per the spec, the address for a block is in units of 1MB */ *new_offset = ROUND_UP(*new_offset, 1024 * 1024); + if (*new_offset > INT64_MAX) { + return -EINVAL; + } return bdrv_truncate(bs->file, *new_offset + s->block_size, PREALLOC_MODE_OFF, NULL); -- 2.9.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() 2017-08-07 3:08 ` [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() Jeff Cody @ 2017-08-07 10:48 ` Kevin Wolf 2017-08-07 11:24 ` [Qemu-devel] " Eric Blake 1 sibling, 0 replies; 10+ messages in thread From: Kevin Wolf @ 2017-08-07 10:48 UTC (permalink / raw) To: Jeff Cody; +Cc: qemu-devel, armbru, qemu-block Am 07.08.2017 um 05:08 hat Jeff Cody geschrieben: > VHDX uses uint64_t types for most offsets, following the VHDX spec. > However, bdrv_truncate() takes an int64_t value for the truncating > offset. Check for overflow before calling bdrv_truncate(). > > N.B.: For a compliant image this is not an issue, as the maximum VHDX > image size is defined per the spec to be 64TB. > > Signed-off-by: Jeff Cody <jcody@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() 2017-08-07 3:08 ` [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() Jeff Cody 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] " Kevin Wolf @ 2017-08-07 11:24 ` Eric Blake 2017-08-07 12:13 ` Jeff Cody 1 sibling, 1 reply; 10+ messages in thread From: Eric Blake @ 2017-08-07 11:24 UTC (permalink / raw) To: Jeff Cody, qemu-devel; +Cc: armbru, qemu-block [-- Attachment #1: Type: text/plain, Size: 1432 bytes --] On 08/06/2017 10:08 PM, Jeff Cody wrote: > VHDX uses uint64_t types for most offsets, following the VHDX spec. > However, bdrv_truncate() takes an int64_t value for the truncating > offset. Check for overflow before calling bdrv_truncate(). > > N.B.: For a compliant image this is not an issue, as the maximum VHDX > image size is defined per the spec to be 64TB. > > Signed-off-by: Jeff Cody <jcody@redhat.com> > --- > block/vhdx-log.c | 4 ++++ > block/vhdx.c | 3 +++ > 2 files changed, 7 insertions(+) > > diff --git a/block/vhdx-log.c b/block/vhdx-log.c > index fd4e7af..3b74e5d 100644 > --- a/block/vhdx-log.c > +++ b/block/vhdx-log.c > @@ -554,6 +554,10 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > if (new_file_size % (1024*1024)) { > /* round up to nearest 1MB boundary */ > new_file_size = ((new_file_size >> 20) + 1) << 20; Since you're touching here, can you fix this to use QEMU_ALIGN_UP instead? > + if (new_file_size > INT64_MAX) { > + ret = -EINVAL; > + goto exit; > + } > bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); Reviewed-by: Eric Blake <eblake@redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 619 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() 2017-08-07 11:24 ` [Qemu-devel] " Eric Blake @ 2017-08-07 12:13 ` Jeff Cody 0 siblings, 0 replies; 10+ messages in thread From: Jeff Cody @ 2017-08-07 12:13 UTC (permalink / raw) To: Eric Blake; +Cc: qemu-devel, armbru, qemu-block On Mon, Aug 07, 2017 at 06:24:30AM -0500, Eric Blake wrote: > On 08/06/2017 10:08 PM, Jeff Cody wrote: > > VHDX uses uint64_t types for most offsets, following the VHDX spec. > > However, bdrv_truncate() takes an int64_t value for the truncating > > offset. Check for overflow before calling bdrv_truncate(). > > > > N.B.: For a compliant image this is not an issue, as the maximum VHDX > > image size is defined per the spec to be 64TB. > > > > Signed-off-by: Jeff Cody <jcody@redhat.com> > > --- > > block/vhdx-log.c | 4 ++++ > > block/vhdx.c | 3 +++ > > 2 files changed, 7 insertions(+) > > > > diff --git a/block/vhdx-log.c b/block/vhdx-log.c > > index fd4e7af..3b74e5d 100644 > > --- a/block/vhdx-log.c > > +++ b/block/vhdx-log.c > > @@ -554,6 +554,10 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, > > if (new_file_size % (1024*1024)) { > > /* round up to nearest 1MB boundary */ > > new_file_size = ((new_file_size >> 20) + 1) << 20; > > Since you're touching here, can you fix this to use QEMU_ALIGN_UP instead? > Good idea, yes. > > + if (new_file_size > INT64_MAX) { > > + ret = -EINVAL; > > + goto exit; > > + } > > bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); > > Reviewed-by: Eric Blake <eblake@redhat.com> > > -- > Eric Blake, Principal Software Engineer > Red Hat, Inc. +1-919-301-3266 > Virtualization: qemu.org | libvirt.org > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH 0/2] VHDX cleanup 2017-08-07 3:08 [Qemu-devel] [PATCH 0/2] VHDX cleanup Jeff Cody 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody 2017-08-07 3:08 ` [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() Jeff Cody @ 2017-08-07 10:48 ` Kevin Wolf 2 siblings, 0 replies; 10+ messages in thread From: Kevin Wolf @ 2017-08-07 10:48 UTC (permalink / raw) To: Jeff Cody; +Cc: qemu-devel, armbru, qemu-block Am 07.08.2017 um 05:08 hat Jeff Cody geschrieben: > Two VHDX items cleaned up: > > 1. Check for error when calling bdrv_getlength() [Markus] > > 2. Check for overflow in offset prior to calling bdrv_truncate(). This doesn't look like cleanups to me, but like proper fixes. I think it would still qualify for 2.10. Kevin ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2017-08-07 12:17 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-07 3:08 [Qemu-devel] [PATCH 0/2] VHDX cleanup Jeff Cody 2017-08-07 3:08 ` [Qemu-devel] [PATCH 1/2] block/vhdx: check error return of bdrv_getlength() Jeff Cody 2017-08-07 10:46 ` [Qemu-devel] [Qemu-block] " Kevin Wolf 2017-08-07 12:16 ` Jeff Cody 2017-08-07 11:25 ` [Qemu-devel] " Eric Blake 2017-08-07 3:08 ` [Qemu-devel] [PATCH 2/2] block/vhdx: check for offset overflow to bdrv_truncate() Jeff Cody 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] " Kevin Wolf 2017-08-07 11:24 ` [Qemu-devel] " Eric Blake 2017-08-07 12:13 ` Jeff Cody 2017-08-07 10:48 ` [Qemu-devel] [Qemu-block] [PATCH 0/2] VHDX cleanup Kevin Wolf
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).