From: John Snow <jsnow@redhat.com>
To: Peter Wu <peter@lekensteyn.nl>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2 08/12] block/dmg: fix sector data offset calculation
Date: Wed, 07 Jan 2015 13:08:24 -0500 [thread overview]
Message-ID: <54AD7618.4060802@redhat.com> (raw)
In-Reply-To: <1420566495-13284-9-git-send-email-peter@lekensteyn.nl>
On 01/06/2015 12:48 PM, Peter Wu wrote:
> This patch addresses two issues:
>
> - The data fork offset was not taken into account, resulting in failure
> to read an InstallESD.dmg file (5164763151 bytes) which had a
> non-zero DataForkOffset field.
> - The offset of the previous block ("partition") was unconditionally
> added to the current block because older files would start the input
> offset of a new block at zero. Newer files (including vlc-2.1.5.dmg,
> tuxpaint-0.9.15-macosx.dmg and OS X Yosemite [MAS].dmg) failed in
> reads because these files have chunk offsets, relative to the begin
> of a data fork.
>
> Now the data offset of the mish is taken into account. While we could
> check that the data_offset is within the data fork, let's not do that
> here as it would only result in parse failures on invalid files (rather
> than gracefully handling such bad files). dmg_read will error out if
> the offset is incorrect.
>
> Signed-off-by: Peter Wu <peter@lekensteyn.nl>
> ---
> v2: use sector and data offset as provided by the BLKX header. This
> allows us to drop last_in_offset. The previous heuristics to detect
> relative offsets is not needed anymore. Squashed the data fork
> offset length check into this patch.
> ---
> block/dmg.c | 26 ++++++++++++++++++++------
> 1 file changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/block/dmg.c b/block/dmg.c
> index 57feb1b..130efac 100644
> --- a/block/dmg.c
> +++ b/block/dmg.c
> @@ -188,7 +188,7 @@ static int64_t dmg_find_koly_offset(BlockDriverState *file_bs, Error **errp)
> typedef struct DmgHeaderState {
> /* used internally by dmg_read_mish_block to remember offsets of blocks
> * across calls */
> - uint64_t last_in_offset;
> + uint64_t data_fork_offset;
> uint64_t last_out_offset;
> /* exported for dmg_open */
> uint32_t max_compressed_size;
> @@ -203,6 +203,8 @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
> size_t new_size;
> uint32_t chunk_count;
> int64_t offset = 0;
> + uint64_t data_offset;
> + uint64_t in_offset = ds->data_fork_offset;
>
> type = buff_read_uint32(buffer, offset);
> /* skip data that is not a valid MISH block (invalid magic or too small) */
> @@ -211,8 +213,12 @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
> return 0;
> }
>
> - offset += 4;
> - offset += 200;
> + /* location in data fork for (compressed) blob (in bytes) */
> + data_offset = buff_read_uint64(buffer, offset + 0x18);
> + in_offset += data_offset;
> +
> + /* move to begin of chunk entries */
> + offset += 204;
>
> chunk_count = (count - 204) / 40;
> new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
> @@ -228,7 +234,6 @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
> if (s->types[i] != 0x80000005 && s->types[i] != 1 &&
> s->types[i] != 2) {
> if (s->types[i] == 0xffffffff && i > 0) {
> - ds->last_in_offset = s->offsets[i - 1] + s->lengths[i - 1];
Great!
> ds->last_out_offset = s->sectors[i - 1] +
> s->sectorcounts[i - 1];
> }
> @@ -255,7 +260,7 @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
> }
>
> s->offsets[i] = buff_read_uint64(buffer, offset);
> - s->offsets[i] += ds->last_in_offset;
> + s->offsets[i] += in_offset;
> offset += 8;
>
> s->lengths[i] = buff_read_uint64(buffer, offset);
> @@ -413,7 +418,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> s->n_chunks = 0;
> s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> /* used by dmg_read_mish_block to keep track of the current I/O position */
> - ds.last_in_offset = 0;
> + ds.data_fork_offset = 0;
> ds.last_out_offset = 0;
> ds.max_compressed_size = 1;
> ds.max_sectors_per_chunk = 1;
> @@ -425,6 +430,15 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> goto fail;
> }
>
> + /* offset of data fork (DataForkOffset) */
> + ret = read_uint64(bs, offset + 0x18, &ds.data_fork_offset);
> + if (ret < 0) {
> + goto fail;
> + } else if (ds.data_fork_offset > offset) {
> + ret = -EINVAL;
> + goto fail;
> + }
> +
> /* offset of resource fork (RsrcForkOffset) */
> ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
> if (ret < 0) {
>
Reviewed-by: John Snow <jsnow@redhat.com>
next prev parent reply other threads:[~2015-01-07 18:08 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-06 17:48 [Qemu-devel] [PATCH v2 00/12] block/dmg: (compatibility) fixes and bzip2 support Peter Wu
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 01/12] block/dmg: properly detect the UDIF trailer Peter Wu
2015-01-07 13:19 ` Stefan Hajnoczi
2015-01-07 14:19 ` Peter Wu
2015-01-14 16:17 ` Stefan Hajnoczi
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 02/12] block/dmg: extract mish block decoding functionality Peter Wu
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 03/12] block/dmg: extract processing of resource forks Peter Wu
2015-01-07 18:05 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 04/12] block/dmg: process a buffer instead of reading ints Peter Wu
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 05/12] block/dmg: validate chunk size to avoid overflow Peter Wu
2015-01-07 18:05 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 06/12] block/dmg: process XML plists Peter Wu
2015-01-07 18:06 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 07/12] block/dmg: set virtual size to a non-zero value Peter Wu
2015-01-07 18:07 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 08/12] block/dmg: fix sector data offset calculation Peter Wu
2015-01-07 18:08 ` John Snow [this message]
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 09/12] block/dmg: use SectorNumber from BLKX header Peter Wu
2015-01-07 18:08 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 10/12] block/dmg: factor out block type check Peter Wu
2015-01-07 18:09 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 11/12] block/dmg: support bzip2 block entry types Peter Wu
2015-01-07 11:08 ` Paolo Bonzini
2015-01-07 18:09 ` John Snow
2015-01-06 17:48 ` [Qemu-devel] [PATCH v2 12/12] block/dmg: improve zeroes handling Peter Wu
2015-01-07 18:10 ` John Snow
2015-01-14 16:16 ` [Qemu-devel] [PATCH v2 00/12] block/dmg: (compatibility) fixes and bzip2 support Stefan Hajnoczi
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=54AD7618.4060802@redhat.com \
--to=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=peter@lekensteyn.nl \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.