[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20240904081401.16682-4-konishi.ryusuke@gmail.com>
Date: Wed, 4 Sep 2024 17:13:09 +0900
From: Ryusuke Konishi <konishi.ryusuke@...il.com>
To: Andrew Morton <akpm@...ux-foundation.org>
Cc: linux-nilfs <linux-nilfs@...r.kernel.org>,
syzbot <syzbot+9bff4c7b992038a7409f@...kaller.appspotmail.com>,
syzkaller-bugs@...glegroups.com,
LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH 3/3] nilfs2: fix potential oob read in nilfs_btree_check_delete()
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.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@...il.com>
Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
---
fs/nilfs2/btree.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index dedd3c480842..ef5061bb56da 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -1659,13 +1659,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,
@@ -1674,12 +1677,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;
--
2.43.0
Powered by blists - more mailing lists