From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
To: Lizhi Xu <lizhi.xu@windriver.com>
Cc: syzbot+9bff4c7b992038a7409f@syzkaller.appspotmail.com,
linux-kernel@vger.kernel.org, linux-nilfs@vger.kernel.org,
syzkaller-bugs@googlegroups.com
Subject: Re: [syzbot] [nilfs?] general protection fault in nilfs_btree_insert (2)
Date: Tue, 3 Sep 2024 04:40:21 +0900 [thread overview]
Message-ID: <CAKFNMom+we=aMXZz_f4zVGR6VRO3Zj+y1GC=KZSwLq8MdxO7BQ@mail.gmail.com> (raw)
In-Reply-To: <20240902084101.138971-1-lizhi.xu@windriver.com>
On Mon, Sep 2, 2024 at 5:41 PM Lizhi Xu wrote:
>
> In nilfs_btree_do_lookup, if the number of children in the btree root node is 0,
> path[x].bp_bh will not be initialized by __nilfs_btree_get_block,
> which will result in uaf when executing nilfs-btree_get_nonroot_node
> in nilfs_btree_prepare_insert.
>
> In nilfs_bmap_do_insert will run bop_check_insert, so implement
> bop_check_insert and determine the number of children in the btree root
> node within it. If it is 0, return a negative value to avoid calling
> bop_intsert.
Thank you Lizhi for helping us solve this problem.
However, your proposed patch has a few issues (more on that later),
and this anomaly detection should be done when the root node is read,
not just before insertion. So, instead of adding bop_check_insert, I
will modify the existing sanity check routine
nilfs_btree_root_broken() by adding the following failure condition:
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 862bdf23120e..d390b8ba00d4 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -381,7 +381,8 @@ static int nilfs_btree_root_broken(const struct
nilfs_btree_node *node,
if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
level >= NILFS_BTREE_LEVEL_MAX ||
nchildren < 0 ||
- nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) {
+ nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX ||
+ (nchildren == 0 && level > NILFS_BTREE_LEVEL_NODE_MIN))) {
nilfs_crit(inode->i_sb,
"bad btree root (ino=%lu): level = %d,
flags = 0x%x, nchildren = %d",
inode->i_ino, level, flags, nchildren);
---
Going back to your proposed patch, there are two problems:
(1) nilfs_btree_node_get_nchildren(node) == 0 is a normal state in
itself, so it is not OK to return this as an error.
(2) Even if we use bop_check_insert to perform a sanity check, the
error code that should be returned is -EINVAL.
-ENOENT is an internal error code, but if bop_check_insert() returns
it, it may be wrongly exposed to userspace (i.e. system
calls). If it is -EINVAL, it will be treated as metadata corruption
at the bmap layer with nilfs_bmap_convert_error(), and the error code
will be converted for return to userspace.
So this time I'll be fixing and testing it myself, and will mention
your help in the patch commit log.
Thanks,
Ryusuke Konishi
>
> #syz test
>
> diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
> index 862bdf23120e..d7fa4d914638 100644
> --- a/fs/nilfs2/btree.c
> +++ b/fs/nilfs2/btree.c
> @@ -1231,6 +1231,17 @@ static void nilfs_btree_commit_insert(struct nilfs_bmap *btree,
> nilfs_bmap_set_dirty(btree);
> }
>
> +static int nilfs_btree_check_insert(const struct nilfs_bmap *btree, __u64 key)
> +{
> + struct nilfs_btree_node *node;
> + int level;
> +
> + node = nilfs_btree_get_root(btree);
> + level = nilfs_btree_node_get_level(node);
> + return (level < NILFS_BTREE_LEVEL_NODE_MIN ||
> + nilfs_btree_node_get_nchildren(node) <= 0) ? -ENOENT : 0;
> +}
> +
> static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr)
> {
> struct nilfs_btree_path *path;
> @@ -2385,7 +2396,7 @@ static const struct nilfs_bmap_operations nilfs_btree_ops = {
> .bop_seek_key = nilfs_btree_seek_key,
> .bop_last_key = nilfs_btree_last_key,
>
> - .bop_check_insert = NULL,
> + .bop_check_insert = nilfs_btree_check_insert,
> .bop_check_delete = nilfs_btree_check_delete,
> .bop_gather_data = nilfs_btree_gather_data,
> };
next prev parent reply other threads:[~2024-09-02 19:40 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-01 20:39 [syzbot] [nilfs?] general protection fault in nilfs_btree_insert (2) syzbot
2024-09-02 8:41 ` Lizhi Xu
2024-09-02 10:08 ` syzbot
2024-09-02 19:40 ` Ryusuke Konishi [this message]
2024-09-04 8:13 ` [PATCH 0/3] nilfs2: fix potential issues with empty b-tree nodes Ryusuke Konishi
2024-09-04 8:13 ` [PATCH 1/3] nilfs2: fix potential null-ptr-deref in nilfs_btree_insert() Ryusuke Konishi
2024-09-04 8:13 ` [PATCH 2/3] nilfs2: determine empty node blocks as corrupted Ryusuke Konishi
2024-09-04 8:13 ` [PATCH 3/3] nilfs2: fix potential oob read in nilfs_btree_check_delete() Ryusuke Konishi
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='CAKFNMom+we=aMXZz_f4zVGR6VRO3Zj+y1GC=KZSwLq8MdxO7BQ@mail.gmail.com' \
--to=konishi.ryusuke@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nilfs@vger.kernel.org \
--cc=lizhi.xu@windriver.com \
--cc=syzbot+9bff4c7b992038a7409f@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).