From: Dave Chinner <david@fromorbit.com>
To: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Eric Sesterhenn <snakebyte@gmx.de>,
linux-kernel@vger.kernel.org, xfs@oss.sgi.com,
Pavel Machek <pavel@suse.cz>,
npiggin@yahoo.com.au, Chris Mason <chris.mason@oracle.com>
Subject: [PATCH] Re: Corrupted XFS log replay oops.
Date: Thu, 22 Jan 2009 15:37:47 +1100 [thread overview]
Message-ID: <20090122043747.GU10158@disturbed> (raw)
In-Reply-To: <200901211503.07308.nickpiggin@yahoo.com.au>
On Wed, Jan 21, 2009 at 03:03:06PM +1100, Nick Piggin wrote:
> On Wednesday 21 January 2009 14:57:03 Dave Chinner wrote:
> > > [ 235.250167] ------------[ cut here ]------------
> > > [ 235.250354] kernel BUG at mm/vmalloc.c:164!
> > > [ 235.250478] invalid opcode: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
> > > [ 235.250869] last sysfs file: /sys/block/ram9/range
> > > [ 235.250998] Modules linked in:
......
> > > [ 235.251037] Call Trace:
> > > [ 235.251037] [<c01414cf>] ? trace_hardirqs_on+0xb/0xd
> > > [ 235.251037] [<c018367c>] ? vm_map_ram+0x36e/0x38a
> > > [ 235.251037] [<c03b2e1e>] ? _xfs_buf_map_pages+0x42/0x6d
> > > [ 235.251037] [<c03b3773>] ? xfs_buf_get_noaddr+0xbc/0x11f
> > > [ 235.251037] [<c03a2406>] ? xlog_get_bp+0x5a/0x5d
> > > [ 235.251037] [<c03a28fa>] ? xlog_find_verify_log_record+0x26/0x208
> > > [ 235.251037] [<c03a3521>] ? xlog_find_zeroed+0x1d6/0x214
> > > [ 235.251037] [<c03a3584>] ? xlog_find_head+0x25/0x358
> >
> > .....
> >
> > Ok, that's crashing in the new vmap code. It might take a couple
> > of days before I get a chance to look at this, but I've cc'd Nick Piggin
> > in case he has a chance to look at it before that. It's probably
> > an XFS bug, anyway.
>
> Hmm, it is crashing in BUG_ON(addr >= end); where this could happen
> if XFS asks to map a really huge (or -ve) number of pages and wraps
> the range, or if vmap subsystem returns an address right near the
> end of the address range and addr+size wraps (which would be a bug
> in vmap of course, but I think maybe less likely).
It's a zero length range, not a negative value. A debug XFS would
have assert failed on it, but it was completely unchecked on
production builds. The following patch checks the length of blocks
to build/read/write for being valid. Instead of an oops, we get:
[ 1572.665001] XFS mounting filesystem loop0
[ 1572.666942] XFS: Invalid block length (0x0) given for buffer
[ 1572.667141] XFS: Log inconsistent (didn't find previous header)
[ 1572.667141] XFS: empty log check failed
[ 1572.667141] XFS: log mount/recovery failed: error 5
[ 1572.671487] XFS: log mount failed
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
[XFS] Check buffer lengths in log recovery
Before trying to obtain, read or write a buffer,
check that the buffer length is actually valid. If
it is not valid, then something read in the recovery
process has been corrupted and we should abort
recovery.
Reported-by: Eric Sesterhenn <snakebyte@gmx.de>
---
fs/xfs/xfs_log_recover.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 35cca98..b1047de 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -70,16 +70,21 @@ STATIC void xlog_recover_check_summary(xlog_t *);
xfs_buf_t *
xlog_get_bp(
xlog_t *log,
- int num_bblks)
+ int nbblks)
{
- ASSERT(num_bblks > 0);
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_get_bp(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return NULL;
+ }
if (log->l_sectbb_log) {
- if (num_bblks > 1)
- num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
- num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
+ if (nbblks > 1)
+ nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
+ nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
}
- return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
+ return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
}
void
@@ -102,6 +107,13 @@ xlog_bread(
{
int error;
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_bread(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return EFSCORRUPTED;
+ }
+
if (log->l_sectbb_log) {
blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
@@ -139,6 +151,13 @@ xlog_bwrite(
{
int error;
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_bwrite(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return EFSCORRUPTED;
+ }
+
if (log->l_sectbb_log) {
blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
WARNING: multiple messages have this Message-ID (diff)
From: Dave Chinner <david@fromorbit.com>
To: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Eric Sesterhenn <snakebyte@gmx.de>, Pavel Machek <pavel@suse.cz>,
Chris Mason <chris.mason@oracle.com>,
linux-kernel@vger.kernel.org, npiggin@yahoo.com.au,
xfs@oss.sgi.com
Subject: [PATCH] Re: Corrupted XFS log replay oops.
Date: Thu, 22 Jan 2009 15:37:47 +1100 [thread overview]
Message-ID: <20090122043747.GU10158@disturbed> (raw)
In-Reply-To: <200901211503.07308.nickpiggin@yahoo.com.au>
On Wed, Jan 21, 2009 at 03:03:06PM +1100, Nick Piggin wrote:
> On Wednesday 21 January 2009 14:57:03 Dave Chinner wrote:
> > > [ 235.250167] ------------[ cut here ]------------
> > > [ 235.250354] kernel BUG at mm/vmalloc.c:164!
> > > [ 235.250478] invalid opcode: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
> > > [ 235.250869] last sysfs file: /sys/block/ram9/range
> > > [ 235.250998] Modules linked in:
......
> > > [ 235.251037] Call Trace:
> > > [ 235.251037] [<c01414cf>] ? trace_hardirqs_on+0xb/0xd
> > > [ 235.251037] [<c018367c>] ? vm_map_ram+0x36e/0x38a
> > > [ 235.251037] [<c03b2e1e>] ? _xfs_buf_map_pages+0x42/0x6d
> > > [ 235.251037] [<c03b3773>] ? xfs_buf_get_noaddr+0xbc/0x11f
> > > [ 235.251037] [<c03a2406>] ? xlog_get_bp+0x5a/0x5d
> > > [ 235.251037] [<c03a28fa>] ? xlog_find_verify_log_record+0x26/0x208
> > > [ 235.251037] [<c03a3521>] ? xlog_find_zeroed+0x1d6/0x214
> > > [ 235.251037] [<c03a3584>] ? xlog_find_head+0x25/0x358
> >
> > .....
> >
> > Ok, that's crashing in the new vmap code. It might take a couple
> > of days before I get a chance to look at this, but I've cc'd Nick Piggin
> > in case he has a chance to look at it before that. It's probably
> > an XFS bug, anyway.
>
> Hmm, it is crashing in BUG_ON(addr >= end); where this could happen
> if XFS asks to map a really huge (or -ve) number of pages and wraps
> the range, or if vmap subsystem returns an address right near the
> end of the address range and addr+size wraps (which would be a bug
> in vmap of course, but I think maybe less likely).
It's a zero length range, not a negative value. A debug XFS would
have assert failed on it, but it was completely unchecked on
production builds. The following patch checks the length of blocks
to build/read/write for being valid. Instead of an oops, we get:
[ 1572.665001] XFS mounting filesystem loop0
[ 1572.666942] XFS: Invalid block length (0x0) given for buffer
[ 1572.667141] XFS: Log inconsistent (didn't find previous header)
[ 1572.667141] XFS: empty log check failed
[ 1572.667141] XFS: log mount/recovery failed: error 5
[ 1572.671487] XFS: log mount failed
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
[XFS] Check buffer lengths in log recovery
Before trying to obtain, read or write a buffer,
check that the buffer length is actually valid. If
it is not valid, then something read in the recovery
process has been corrupted and we should abort
recovery.
Reported-by: Eric Sesterhenn <snakebyte@gmx.de>
---
fs/xfs/xfs_log_recover.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 35cca98..b1047de 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -70,16 +70,21 @@ STATIC void xlog_recover_check_summary(xlog_t *);
xfs_buf_t *
xlog_get_bp(
xlog_t *log,
- int num_bblks)
+ int nbblks)
{
- ASSERT(num_bblks > 0);
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_get_bp(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return NULL;
+ }
if (log->l_sectbb_log) {
- if (num_bblks > 1)
- num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
- num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
+ if (nbblks > 1)
+ nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
+ nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
}
- return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
+ return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
}
void
@@ -102,6 +107,13 @@ xlog_bread(
{
int error;
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_bread(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return EFSCORRUPTED;
+ }
+
if (log->l_sectbb_log) {
blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
@@ -139,6 +151,13 @@ xlog_bwrite(
{
int error;
+ if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+ xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+ XFS_ERROR_REPORT("xlog_bwrite(1)",
+ XFS_ERRLEVEL_HIGH, log->l_mp);
+ return EFSCORRUPTED;
+ }
+
if (log->l_sectbb_log) {
blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
next prev parent reply other threads:[~2009-01-22 4:44 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-13 14:21 Warning and BUG with btrfs and corrupted image Eric Sesterhenn
2009-01-13 14:40 ` Chris Mason
2009-01-13 14:43 ` Eric Sesterhenn
2009-01-15 2:13 ` Chris Mason
2009-01-18 17:40 ` Pavel Machek
2009-01-20 6:31 ` Eric Sesterhenn
2009-01-20 9:34 ` Pavel Machek
2009-01-20 10:11 ` Dave Chinner
2009-01-20 10:15 ` Eric Sesterhenn
2009-01-20 12:59 ` Dave Chinner
2009-01-20 13:28 ` Christoph Hellwig
2009-01-20 22:20 ` Pavel Machek
2009-01-21 4:00 ` Dave Chinner
2009-01-26 16:27 ` Pavel Machek
2009-01-26 20:06 ` [Discussion] Apparent inconsistancies in use of io_align, io_width & sector_size ashford
2009-02-01 1:40 ` Warning and BUG with btrfs and corrupted image Dave Chinner
2009-02-04 18:29 ` Pavel Machek
2009-02-05 8:59 ` Dave Chinner
2009-02-05 8:59 ` Dave Chinner
2009-02-05 9:02 ` Pavel Machek
2009-02-05 13:02 ` Chris Mason
2009-02-05 13:50 ` Pavel Machek
2009-02-05 14:19 ` jim owens
2009-02-25 19:54 ` Pavel Machek
2009-01-20 17:34 ` Eric Sesterhenn
2009-01-20 22:18 ` Pavel Machek
2009-01-21 9:36 ` Eric Sesterhenn
2009-01-21 3:57 ` Corrupted XFS log replay oops. (was Re: Warning and BUG with btrfs and corrupted image) Dave Chinner
2009-01-21 3:57 ` Dave Chinner
2009-01-21 4:03 ` Nick Piggin
2009-01-22 4:37 ` Dave Chinner [this message]
2009-01-22 4:37 ` [PATCH] Re: Corrupted XFS log replay oops Dave Chinner
2009-01-22 5:50 ` Felix Blyakher
2009-01-22 5:50 ` Felix Blyakher
2009-01-22 6:11 ` Christoph Hellwig
2009-01-22 6:11 ` Christoph Hellwig
2009-01-22 8:35 ` Eric Sesterhenn
2009-01-22 8:35 ` Eric Sesterhenn
2009-01-22 10:06 ` Eric Sesterhenn
2009-01-22 10:06 ` Eric Sesterhenn
2009-01-22 23:37 ` Dave Chinner
2009-01-22 23:37 ` Dave Chinner
2009-01-23 1:10 ` Dave Chinner
2009-01-23 1:10 ` Dave Chinner
2009-01-22 23:35 ` Dave Chinner
2009-01-22 23:35 ` Dave Chinner
2009-01-23 0:02 ` Dave Chinner
2009-01-23 0:02 ` Dave Chinner
2009-01-23 0:06 ` Christoph Hellwig
2009-01-23 0:06 ` Christoph Hellwig
2009-01-23 6:20 ` Felix Blyakher
2009-01-23 6:20 ` Felix Blyakher
2009-02-03 20:48 ` Eric Sandeen
2009-01-21 4:03 ` Corrupted XFS log replay oops. (was Re: Warning and BUG with btrfs and corrupted image) Dave Chinner
2009-01-21 4:03 ` Dave Chinner
2009-01-20 13:11 ` Warning and BUG with btrfs and corrupted image Chris Mason
2009-01-20 16:51 ` Eric Sesterhenn
2009-01-22 2:15 ` Phillip Lougher
2009-01-23 8:56 ` Eric Sesterhenn
2009-01-23 8:56 ` Eric Sesterhenn
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=20090122043747.GU10158@disturbed \
--to=david@fromorbit.com \
--cc=chris.mason@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nickpiggin@yahoo.com.au \
--cc=npiggin@yahoo.com.au \
--cc=pavel@suse.cz \
--cc=snakebyte@gmx.de \
--cc=xfs@oss.sgi.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.