[PATCH] jfs: return -ENOSPC instead of BUG() on corrupted dmap tree in dbFindLeaf

Nguyen Ngoc Thang posted 1 patch 1 week, 5 days ago
fs/jfs/jfs_dmap.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
[PATCH] jfs: return -ENOSPC instead of BUG() on corrupted dmap tree in dbFindLeaf
Posted by Nguyen Ngoc Thang 1 week, 5 days ago
dbFindLeaf() trusts the on-disk dmtree summary values: the root level
says free space exists, then it searches each level's 4 children for
one that actually provides it. A corrupted (e.g. crafted/fuzzed) JFS
image can have a parent claim space that none of its children provide,
which is neither validated on mount nor recoverable here -- it used to
hit assert(n < 4), i.e. BUG(), crashing the kernel. Treat it the same
way as the two existing sanity checks in this function and return
-ENOSPC instead.

Reported-by: syzbot+dcea2548c903300a400e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dcea2548c903300a400e
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
---
 fs/jfs/jfs_dmap.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index a841cf21da7d..079765450bb2 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -3065,9 +3065,12 @@ static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
 		}
 
 		/* better have found something since the higher
-		 * levels of the tree said it was here.
+		 * levels of the tree said it was here. A corrupted tree
+		 * can claim free space at a level that no child actually
+		 * provides.
 		 */
-		assert(n < 4);
+		if (n == 4)
+			return -ENOSPC;
 	}
 	if (le32_to_cpu(tp->dmt_leafidx) >= max_idx)
 		return -ENOSPC;
-- 
2.43.0