From 17e6afc75ad0150d265a86a8f155b2871f9c07fe Mon Sep 17 00:00:00 2001
From: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Date: Tue, 9 Jan 2007 08:57:34 -0600
Subject: JFS: Avoid BUG() on a damaged file system

On Mon, 2006-12-18 at 19:51 +0100, Eric Sesterhenn wrote:
> hi,
>
> while playing around with fsfuzzer, i got the following oops with jfs:
>
> [  851.804875] BUG at fs/jfs/jfs_xtree.c:760
> assert(!BT_STACK_FULL(btstack))
> [  851.805179] ------------[ cut here ]------------
> [  851.805238] kernel BUG at fs/jfs/jfs_xtree.c:760!

JFS should mark the superblock dirty and return an error rather than
calling BUG().

Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
 fs/jfs/jfs_xtree.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

(limited to 'fs')

diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index e98eb03e53..acc97c46d8 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -757,6 +757,11 @@ static int xtSearch(struct inode *ip, s64 xoff,	s64 *nextp,
 			nsplit = 0;
 
 		/* push (bn, index) of the parent page/entry */
+		if (BT_STACK_FULL(btstack)) {
+			jfs_error(ip->i_sb, "stack overrun in xtSearch!");
+			XT_PUTPAGE(mp);
+			return -EIO;
+		}
 		BT_PUSH(btstack, bn, index);
 
 		/* get the child page block number */
@@ -3915,6 +3920,11 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
 	 */
       getChild:
 	/* save current parent entry for the child page */
+	if (BT_STACK_FULL(&btstack)) {
+		jfs_error(ip->i_sb, "stack overrun in xtTruncate!");
+		XT_PUTPAGE(mp);
+		return -EIO;
+	}
 	BT_PUSH(&btstack, bn, index);
 
 	/* get child page */
@@ -4112,6 +4122,11 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
 	 */
       getChild:
 	/* save current parent entry for the child page */
+	if (BT_STACK_FULL(&btstack)) {
+		jfs_error(ip->i_sb, "stack overrun in xtTruncate_pmap!");
+		XT_PUTPAGE(mp);
+		return -EIO;
+	}
 	BT_PUSH(&btstack, bn, index);
 
 	/* get child page */
-- 
cgit v1.2.2