Message ID | 1321969832-21662-2-git-send-email-apw@canonical.com |
---|---|
State | New |
Headers | show |
On Tue, Nov 22, 2011 at 01:50:32PM +0000, Andy Whitcroft wrote: > From: Eryu Guan <guaneryu@gmail.com> > > I hit a J_ASSERT(blocknr != 0) failure in cleanup_journal_tail() when > mounting a fsfuzzed ext3 image. It turns out that the corrupted ext3 > image has s_first = 0 in journal superblock, and the 0 is passed to > journal->j_head in journal_reset(), then to blocknr in > cleanup_journal_tail(), in the end the J_ASSERT failed. > > So validate s_first after reading journal superblock from disk in > journal_get_superblock() to ensure s_first is valid. > > The following script could reproduce it: > > fstype=ext3 > blocksize=1024 > img=$fstype.img > offset=0 > found=0 > magic="c0 3b 39 98" > > dd if=/dev/zero of=$img bs=1M count=8 > mkfs -t $fstype -b $blocksize -F $img > filesize=`stat -c %s $img` > while [ $offset -lt $filesize ] > do > if od -j $offset -N 4 -t x1 $img | grep -i "$magic";then > echo "Found journal: $offset" > found=1 > break > fi > offset=`echo "$offset+$blocksize" | bc` > done > > if [ $found -ne 1 ];then > echo "Magic \"$magic\" not found" > exit 1 > fi > > dd if=/dev/zero of=$img seek=$(($offset+23)) conv=notrunc bs=1 count=1 > > mkdir -p ./mnt > mount -o loop $img ./mnt > > Cc: Jan Kara <jack@suse.cz> > Signed-off-by: Eryu Guan <guaneryu@gmail.com> > Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> > > (cherry picked from commit 8762202dd0d6e46854f786bdb6fb3780a1625efe) > CVE-2011-4132 > BugLink: http://bugs.launchpad.net/bugs/893148 > Signed-off-by: Andy Whitcroft <apw@canonical.com> > --- > fs/jbd/journal.c | 8 ++++++++ > fs/jbd2/journal.c | 8 ++++++++ > 2 files changed, 16 insertions(+), 0 deletions(-) > > diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c > index 5d14243..6ad18ba 100644 > --- a/fs/jbd/journal.c > +++ b/fs/jbd/journal.c > @@ -1030,6 +1030,14 @@ static int journal_get_superblock(journal_t *journal) > goto out; > } > > + if (be32_to_cpu(sb->s_first) == 0 || > + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { > + printk(KERN_WARNING > + "JBD: Invalid start block of journal: %u\n", > + be32_to_cpu(sb->s_first)); > + goto out; > + } > + > return 0; > > out: > diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c > index 6ddc553..33eb17c 100644 > --- a/fs/jbd2/journal.c > +++ b/fs/jbd2/journal.c > @@ -1029,6 +1029,14 @@ static int journal_get_superblock(journal_t *journal) > goto out; > } > > + if (be32_to_cpu(sb->s_first) == 0 || > + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { > + printk(KERN_WARNING > + "JBD2: Invalid start block of journal: %u\n", > + be32_to_cpu(sb->s_first)); > + goto out; > + } > + > return 0; > > out: > -- > 1.7.5.4 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team >
On 22.11.2011 14:50, Andy Whitcroft wrote: > From: Eryu Guan <guaneryu@gmail.com> > > I hit a J_ASSERT(blocknr != 0) failure in cleanup_journal_tail() when > mounting a fsfuzzed ext3 image. It turns out that the corrupted ext3 > image has s_first = 0 in journal superblock, and the 0 is passed to > journal->j_head in journal_reset(), then to blocknr in > cleanup_journal_tail(), in the end the J_ASSERT failed. > > So validate s_first after reading journal superblock from disk in > journal_get_superblock() to ensure s_first is valid. > > The following script could reproduce it: > > fstype=ext3 > blocksize=1024 > img=$fstype.img > offset=0 > found=0 > magic="c0 3b 39 98" > > dd if=/dev/zero of=$img bs=1M count=8 > mkfs -t $fstype -b $blocksize -F $img > filesize=`stat -c %s $img` > while [ $offset -lt $filesize ] > do > if od -j $offset -N 4 -t x1 $img | grep -i "$magic";then > echo "Found journal: $offset" > found=1 > break > fi > offset=`echo "$offset+$blocksize" | bc` > done > > if [ $found -ne 1 ];then > echo "Magic \"$magic\" not found" > exit 1 > fi > > dd if=/dev/zero of=$img seek=$(($offset+23)) conv=notrunc bs=1 count=1 > > mkdir -p ./mnt > mount -o loop $img ./mnt > > Cc: Jan Kara <jack@suse.cz> > Signed-off-by: Eryu Guan <guaneryu@gmail.com> > Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> > > (cherry picked from commit 8762202dd0d6e46854f786bdb6fb3780a1625efe) > CVE-2011-4132 > BugLink: http://bugs.launchpad.net/bugs/893148 > Signed-off-by: Andy Whitcroft <apw@canonical.com> > --- > fs/jbd/journal.c | 8 ++++++++ > fs/jbd2/journal.c | 8 ++++++++ > 2 files changed, 16 insertions(+), 0 deletions(-) > > diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c > index 5d14243..6ad18ba 100644 > --- a/fs/jbd/journal.c > +++ b/fs/jbd/journal.c > @@ -1030,6 +1030,14 @@ static int journal_get_superblock(journal_t *journal) > goto out; > } > > + if (be32_to_cpu(sb->s_first) == 0 || > + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { > + printk(KERN_WARNING > + "JBD: Invalid start block of journal: %u\n", > + be32_to_cpu(sb->s_first)); > + goto out; > + } > + > return 0; > > out: > diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c > index 6ddc553..33eb17c 100644 > --- a/fs/jbd2/journal.c > +++ b/fs/jbd2/journal.c > @@ -1029,6 +1029,14 @@ static int journal_get_superblock(journal_t *journal) > goto out; > } > > + if (be32_to_cpu(sb->s_first) == 0 || > + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { > + printk(KERN_WARNING > + "JBD2: Invalid start block of journal: %u\n", > + be32_to_cpu(sb->s_first)); > + goto out; > + } > + > return 0; > > out: Looks ok
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 5d14243..6ad18ba 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -1030,6 +1030,14 @@ static int journal_get_superblock(journal_t *journal) goto out; } + if (be32_to_cpu(sb->s_first) == 0 || + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { + printk(KERN_WARNING + "JBD: Invalid start block of journal: %u\n", + be32_to_cpu(sb->s_first)); + goto out; + } + return 0; out: diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 6ddc553..33eb17c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1029,6 +1029,14 @@ static int journal_get_superblock(journal_t *journal) goto out; } + if (be32_to_cpu(sb->s_first) == 0 || + be32_to_cpu(sb->s_first) >= journal->j_maxlen) { + printk(KERN_WARNING + "JBD2: Invalid start block of journal: %u\n", + be32_to_cpu(sb->s_first)); + goto out; + } + return 0; out: