From patchwork Tue Nov 22 13:50:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 127077 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 8DA501007D1 for ; Wed, 23 Nov 2011 00:50:53 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1RSqkE-0003dP-IU; Tue, 22 Nov 2011 13:50:42 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1RSqk6-0003cK-UJ for kernel-team@lists.ubuntu.com; Tue, 22 Nov 2011 13:50:34 +0000 Received: from [85.210.145.47] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1RSqk6-00049g-Ou; Tue, 22 Nov 2011 13:50:34 +0000 From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [hardy, lucid, lucid/fsl-imx51, maverick, maverick/ti-omap4, natty, natty/ti-omap4, oneiric CVE 1/1] jbd/jbd2: validate sb->s_first in journal_get_superblock() Date: Tue, 22 Nov 2011 13:50:32 +0000 Message-Id: <1321969832-21662-2-git-send-email-apw@canonical.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1321969832-21662-1-git-send-email-apw@canonical.com> References: <1321969832-21662-1-git-send-email-apw@canonical.com> Cc: Andy Whitcroft X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Eryu Guan 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 Signed-off-by: Eryu Guan Signed-off-by: "Theodore Ts'o" (cherry picked from commit 8762202dd0d6e46854f786bdb6fb3780a1625efe) CVE-2011-4132 BugLink: http://bugs.launchpad.net/bugs/893148 Signed-off-by: Andy Whitcroft --- 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: