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 03/12] block/dmg: extract processing of resource forks
Date: Wed, 07 Jan 2015 13:05:17 -0500 [thread overview]
Message-ID: <54AD755D.2000108@redhat.com> (raw)
In-Reply-To: <1420566495-13284-4-git-send-email-peter@lekensteyn.nl>
On 01/06/2015 12:48 PM, Peter Wu wrote:
> Besides the offset, also read the resource length. This length is now
> used in the extracted function to verify the end of the resource fork
> against "count" from the resource fork.
>
> Instead of relying on the value of offset to conclude whether the
> resource fork is available or not (info_begin==0), check the
> rsrc_fork_length instead. This would allow a dmg file to begin with a
> resource fork. This seemingly unnecessary restriction was found while
> trying to craft a DMG file by hand.
>
> Other changes:
>
> - Do not require resource data offset to be 0x100 (but check that it
> is within bounds though).
> - Further improve boundary checking (resource data must be within
> the resource fork).
> - Use correct value for resource data length (spotted by John Snow)
> - Consider the resource data offset when determining info_end.
> This fixes an EINVAL on the tuxpaint dmg example.
>
> The resource fork format is documented at
> https://developer.apple.com/legacy/library/documentation/mac/pdf/MoreMacintoshToolbox.pdf#page=151
>
> Signed-off-by: Peter Wu <peter@lekensteyn.nl>
> ---
> v2: expanded commit message (incl. documentation link). Do not require
> a fixed resource data offset of 0x100, improve boundary checking,
> fix resource data len (8 vs 4), append offset when checking the end
> of the resource data.
> --
> block/dmg.c | 104 ++++++++++++++++++++++++++++++++++++++----------------------
> 1 file changed, 66 insertions(+), 38 deletions(-)
>
> diff --git a/block/dmg.c b/block/dmg.c
> index e01559f..ed99cf5 100644
> --- a/block/dmg.c
> +++ b/block/dmg.c
> @@ -287,60 +287,38 @@ fail:
> return ret;
> }
>
> -static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> - Error **errp)
> +static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
> + uint64_t info_begin, uint64_t info_length)
> {
> - BDRVDMGState *s = bs->opaque;
> - DmgHeaderState ds;
> - uint64_t info_begin, info_end;
> - uint32_t count, rsrc_data_offset;
> - int64_t offset;
> int ret;
> + uint32_t count, rsrc_data_offset;
> + uint64_t info_end;
> + uint64_t offset;
>
> - bs->read_only = 1;
> - 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.last_out_offset = 0;
> - ds.max_compressed_size = 1;
> - ds.max_sectors_per_chunk = 1;
> -
> - /* locate the UDIF trailer */
> - offset = dmg_find_koly_offset(bs->file, errp);
> - if (offset < 0) {
> - ret = offset;
> - goto fail;
> - }
> -
> - ret = read_uint64(bs, offset + 0x28, &info_begin);
> - if (ret < 0) {
> - goto fail;
> - } else if (info_begin == 0) {
> - ret = -EINVAL;
> - goto fail;
> - }
> -
> + /* read offset from begin of resource fork (info_begin) to resource data */
> ret = read_uint32(bs, info_begin, &rsrc_data_offset);
> if (ret < 0) {
> goto fail;
> - } else if (rsrc_data_offset != 0x100) {
> + } else if (rsrc_data_offset > info_length) {
> ret = -EINVAL;
> goto fail;
> }
>
> - ret = read_uint32(bs, info_begin + 4, &count);
> + /* read length of resource data */
> + ret = read_uint32(bs, info_begin + 8, &count);
> if (ret < 0) {
> goto fail;
> - } else if (count == 0) {
> + } else if (count == 0 || rsrc_data_offset + count > info_length) {
> ret = -EINVAL;
> goto fail;
> }
> - /* end of resource data, ignoring the following resource map */
> - info_end = info_begin + count;
>
> /* begin of resource data (consisting of one or more resources) */
> - offset = info_begin + 0x100;
> + offset = info_begin + rsrc_data_offset;
> +
> + /* end of resource data (there is possibly a following resource map
> + * which will be ignored). */
> + info_end = offset + count;
>
> /* read offsets (mish blocks) from one or more resources in resource data */
> while (offset < info_end) {
> @@ -354,13 +332,63 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> }
> offset += 4;
>
> - ret = dmg_read_mish_block(bs, &ds, offset, count);
> + ret = dmg_read_mish_block(bs, ds, offset, count);
> if (ret < 0) {
> goto fail;
> }
> /* advance offset by size of resource */
> offset += count;
> }
> + return 0;
> +
> +fail:
> + return ret;
> +}
> +
> +static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> + Error **errp)
> +{
> + BDRVDMGState *s = bs->opaque;
> + DmgHeaderState ds;
> + uint64_t rsrc_fork_offset, rsrc_fork_length;
> + int64_t offset;
> + int ret;
> +
> + bs->read_only = 1;
> + 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.last_out_offset = 0;
> + ds.max_compressed_size = 1;
> + ds.max_sectors_per_chunk = 1;
> +
> + /* locate the UDIF trailer */
> + offset = dmg_find_koly_offset(bs->file, errp);
> + if (offset < 0) {
> + ret = offset;
> + goto fail;
> + }
> +
> + /* offset of resource fork (RsrcForkOffset) */
> + ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
> + if (ret < 0) {
> + goto fail;
> + }
> + ret = read_uint64(bs, offset + 0x30, &rsrc_fork_length);
> + if (ret < 0) {
> + goto fail;
> + }
> + if (rsrc_fork_length != 0) {
> + ret = dmg_read_resource_fork(bs, &ds,
> + rsrc_fork_offset, rsrc_fork_length);
> + if (ret < 0) {
> + goto fail;
> + }
> + } else {
> + ret = -EINVAL;
> + goto fail;
> + }
>
> /* initialize zlib engine */
> s->compressed_chunk = qemu_try_blockalign(bs->file,
>
Reviewed-by: John Snow <jsnow@redhat.com>
next prev parent reply other threads:[~2015-01-07 18:05 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 [this message]
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
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=54AD755D.2000108@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.