From: Jan Kara <jack@suse.cz>
To: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Jan Kara <jack@suse.cz>, Jan Kara <jack@suse.com>,
linux-kernel@vger.kernel.org, quentin.casasnovas@oracle.com
Subject: Re: [PATCH] udf: limit the maximum number of TD redirections
Date: Mon, 14 Dec 2015 20:10:41 +0100 [thread overview]
Message-ID: <20151214191041.GK8474@quack.suse.cz> (raw)
In-Reply-To: <566E9588.4010208@oracle.com>
On Mon 14-12-15 11:10:16, Vegard Nossum wrote:
> On 12/14/2015 10:52 AM, Jan Kara wrote:
> >On Thu 10-12-15 17:13:41, Vegard Nossum wrote:
> >>Filesystem fuzzing revealed that we could get stuck in the
> >>udf_process_sequence() loop.
> >>
> >>The maximum limit was chosen arbitrarily but fixes the problem I saw.
> >
> >Process nit: The patch is missing your Signed-off-by.
> >
>
> Oops, sorry! If the patch is still being considered, here it is:
>
> Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
>
> >>diff --git fs/udf/super.c fs/udf/super.c
> >>index 81155b9..fd45537 100644
> >>--- fs/udf/super.c
> >>+++ fs/udf/super.c
> >>@@ -1586,6 +1586,13 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
> >> }
> >>
> >> /*
> >>+ * Maximum number of Terminating Descriptor redirections. The chosen number is
> >>+ * arbitrary - just that we hopefully don't limit any real use of rewritten
> >>+ * inode on write-once media but avoid looping for too long on corrupted media.
> >>+ */
> >>+#define UDF_MAX_TD_NESTING 64
> >>+
> >>+/*
> >> * Process a main/reserve volume descriptor sequence.
> >> * @block First block of first extent of the sequence.
> >> * @lastblock Lastblock of first extent of the sequence.
> >>@@ -1609,6 +1616,7 @@ static noinline int udf_process_sequence(
> >> uint16_t ident;
> >> long next_s = 0, next_e = 0;
> >> int ret;
> >>+ unsigned int indirections = 0;
> >>
> >> memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
> >>
> >>@@ -1679,6 +1687,12 @@ static noinline int udf_process_sequence(
> >> }
> >> break;
> >> case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
> >>+ if (++indirections > UDF_MAX_TD_NESTING) {
> >>+ udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING);
> >>+ brelse(bh);
> >>+ return -EIO;
> >>+ }
> >>+
> >> vds[VDS_POS_TERMINATING_DESC].block = block;
> >> if (next_e) {
> >
> >But this doesn't really help much. When we speak about corrupted media,
> >then most likely we hit a case where descriptor CRCs won't match and so we
> >return EIO. How exactly did your fuzzing corrupt the filesystem? I suppose
> >it hardly created long sequence of correct VDP descriptors just by pure
> >"luck".
>
> I think the problem is circular TD descriptors, i.e. in my case I see
> this loop:
>
> for (; (!done && block <= lastblock); block++) {
>
> going endlessly over blocks {257, 258, 259, 260, 261, 262} without ever
> returning.
I see. I thought this is impossible due to
if (vdsn >= curr->volDescSeqNum) {
check but indeed the inequality is non-strict and thus loops will still be
traversed. Sigh. OK, so your patch makes sense for a malicious fs images.
> I put my check in the TAG_IDENT_TD case because that's where "block" is
> assigned apart from just being incremented, but I see there's some more
> stuff going on with next_s/next_e/lastblock as well (maybe involving
> TAG_IDENT_VDP). However, I don't really know UDF so maybe there is a
> better way to stop the infinite loop from happening.
No, what you did is probably the best we can do with reasonable effort to
avoid infinite loops. So I'll take your patch.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
prev parent reply other threads:[~2015-12-14 19:10 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-10 16:13 [PATCH] udf: limit the maximum number of TD redirections Vegard Nossum
2015-12-14 9:52 ` Jan Kara
2015-12-14 10:10 ` Vegard Nossum
2015-12-14 19:10 ` Jan Kara [this message]
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=20151214191041.GK8474@quack.suse.cz \
--to=jack@suse.cz \
--cc=jack@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=quentin.casasnovas@oracle.com \
--cc=vegard.nossum@oracle.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