Skip to content

Commit

Permalink
nilfs2: fix potential oob read in nilfs_btree_check_delete()
Browse files Browse the repository at this point in the history
[ Upstream commit f9c96351aa6718b42a9f42eaf7adce0356bdb5e8 ]

The function nilfs_btree_check_delete(), which checks whether degeneration
to direct mapping occurs before deleting a b-tree entry, causes memory
access outside the block buffer when retrieving the maximum key if the
root node has no entries.

This does not usually happen because b-tree mappings with 0 child nodes
are never created by mkfs.nilfs2 or nilfs2 itself.  However, it can happen
if the b-tree root node read from a device is configured that way, so fix
this potential issue by adding a check for that case.

Link: https://lkml.kernel.org/r/20240904081401.16682-4-konishi.ryusuke@gmail.com
Fixes: 17c76b0 ("nilfs2: B-tree based block mapping")
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Cc: Lizhi Xu <lizhi.xu@windriver.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit f3a9859767c7aea758976f5523903d247e585129)
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
  • Loading branch information
konis authored and selfmusing committed Feb 17, 2025
1 parent 3bea8c2 commit 2400a1e
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions fs/nilfs2/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1669,13 +1669,16 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)
int nchildren, ret;

root = nilfs_btree_get_root(btree);
nchildren = nilfs_btree_node_get_nchildren(root);
if (unlikely(nchildren == 0))
return 0;

switch (nilfs_btree_height(btree)) {
case 2:
bh = NULL;
node = root;
break;
case 3:
nchildren = nilfs_btree_node_get_nchildren(root);
if (nchildren > 1)
return 0;
ptr = nilfs_btree_node_get_ptr(root, nchildren - 1,
Expand All @@ -1684,12 +1687,12 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)
if (ret < 0)
return ret;
node = (struct nilfs_btree_node *)bh->b_data;
nchildren = nilfs_btree_node_get_nchildren(node);
break;
default:
return 0;
}

nchildren = nilfs_btree_node_get_nchildren(node);
maxkey = nilfs_btree_node_get_key(node, nchildren - 1);
nextmaxkey = (nchildren > 1) ?
nilfs_btree_node_get_key(node, nchildren - 2) : 0;
Expand Down

0 comments on commit 2400a1e

Please sign in to comment.