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 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).