Linux NILFS development
 help / color / mirror / Atom feed
* [PATCH 0/2] nilfs2: fix kernel bug at submit_bh_wbc()
       [not found] <0000000000002df264056a35b16b@google.com>
@ 2024-03-13 10:58 ` Ryusuke Konishi
  2024-03-13 10:58   ` [PATCH 1/2] nilfs2: fix failure to detect DAT corruption in btree and direct mappings Ryusuke Konishi
  2024-03-13 10:58   ` [PATCH 2/2] nilfs2: prevent kernel bug at submit_bh_wbc() Ryusuke Konishi
  0 siblings, 2 replies; 3+ messages in thread
From: Ryusuke Konishi @ 2024-03-13 10:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: syzbot, syzkaller-bugs, linux-nilfs, linux-kernel

Hi Andrew,

please apply this series as a bug fix.

This resolves a kernel BUG reported by syzbot.  Since there are two
flaws involved, I've made each one a separate patch.

The first patch alone resolves the syzbot-reported bug, but I think
both fixes should be sent to stable, so I've tagged them as such.

This series does not conflict with the currently queued conversion
to kmap_local series, etc and can be applied independently.

Thanks,
Ryusuke Konishi


Ryusuke Konishi (2):
  nilfs2: fix failure to detect DAT corruption in btree and direct
    mappings
  nilfs2: prevent kernel bug at submit_bh_wbc()

 fs/nilfs2/btree.c  | 9 +++++++--
 fs/nilfs2/direct.c | 9 +++++++--
 fs/nilfs2/inode.c  | 2 +-
 3 files changed, 15 insertions(+), 5 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] nilfs2: fix failure to detect DAT corruption in btree and direct mappings
  2024-03-13 10:58 ` [PATCH 0/2] nilfs2: fix kernel bug at submit_bh_wbc() Ryusuke Konishi
@ 2024-03-13 10:58   ` Ryusuke Konishi
  2024-03-13 10:58   ` [PATCH 2/2] nilfs2: prevent kernel bug at submit_bh_wbc() Ryusuke Konishi
  1 sibling, 0 replies; 3+ messages in thread
From: Ryusuke Konishi @ 2024-03-13 10:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: syzbot, syzkaller-bugs, linux-nilfs, linux-kernel

Syzbot has reported a kernel bug in submit_bh_wbc() when writing file
data to a nilfs2 file system whose metadata is corrupted.

There are two flaws involved in this issue.

The first flaw is that when nilfs_get_block() locates a data block
using btree or direct mapping, if the disk address translation routine
nilfs_dat_translate() fails with internal code -ENOENT due to DAT
metadata corruption, it can be passed back to nilfs_get_block().  This
causes nilfs_get_block() to misidentify an existing block as
non-existent, causing both data block lookup and insertion to fail
inconsistently.

The second flaw is that nilfs_get_block() returns a successful status
in this inconsistent state.  This causes the caller
__block_write_begin_int() or others to request a read even though the
buffer is not mapped, resulting in a BUG_ON check for the BH_Mapped
flag in submit_bh_wbc() failing.

This fixes the first issue by changing the return value to code
-EINVAL when a conversion using DAT fails with code -ENOENT, avoiding
the conflicting condition that leads to the kernel bug described
above.  Here, code -EINVAL indicates that metadata corruption was
detected during the block lookup, which will be properly handled as a
file system error and converted to -EIO when passing through the
nilfs2 bmap layer.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Reported-by: syzbot+cfed5b56649bddf80d6e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=cfed5b56649bddf80d6e
Fixes: c3a7abf06ce7 ("nilfs2: support contiguous lookup of blocks")
Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Cc: stable@vger.kernel.org
---
 fs/nilfs2/btree.c  | 9 +++++++--
 fs/nilfs2/direct.c | 9 +++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 13592e82eaf6..65659fa0372e 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -724,7 +724,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
 		dat = nilfs_bmap_get_dat(btree);
 		ret = nilfs_dat_translate(dat, ptr, &blocknr);
 		if (ret < 0)
-			goto out;
+			goto dat_error;
 		ptr = blocknr;
 	}
 	cnt = 1;
@@ -743,7 +743,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
 			if (dat) {
 				ret = nilfs_dat_translate(dat, ptr2, &blocknr);
 				if (ret < 0)
-					goto out;
+					goto dat_error;
 				ptr2 = blocknr;
 			}
 			if (ptr2 != ptr + cnt || ++cnt == maxblocks)
@@ -781,6 +781,11 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
  out:
 	nilfs_btree_free_path(path);
 	return ret;
+
+ dat_error:
+	if (ret == -ENOENT)
+		ret = -EINVAL;  /* Notify bmap layer of metadata corruption */
+	goto out;
 }
 
 static void nilfs_btree_promote_key(struct nilfs_bmap *btree,
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
index 4c85914f2abc..893ab36824cc 100644
--- a/fs/nilfs2/direct.c
+++ b/fs/nilfs2/direct.c
@@ -66,7 +66,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
 		dat = nilfs_bmap_get_dat(direct);
 		ret = nilfs_dat_translate(dat, ptr, &blocknr);
 		if (ret < 0)
-			return ret;
+			goto dat_error;
 		ptr = blocknr;
 	}
 
@@ -79,7 +79,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
 		if (dat) {
 			ret = nilfs_dat_translate(dat, ptr2, &blocknr);
 			if (ret < 0)
-				return ret;
+				goto dat_error;
 			ptr2 = blocknr;
 		}
 		if (ptr2 != ptr + cnt)
@@ -87,6 +87,11 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
 	}
 	*ptrp = ptr;
 	return cnt;
+
+ dat_error:
+	if (ret == -ENOENT)
+		ret = -EINVAL;  /* Notify bmap layer of metadata corruption */
+	return ret;
 }
 
 static __u64
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] nilfs2: prevent kernel bug at submit_bh_wbc()
  2024-03-13 10:58 ` [PATCH 0/2] nilfs2: fix kernel bug at submit_bh_wbc() Ryusuke Konishi
  2024-03-13 10:58   ` [PATCH 1/2] nilfs2: fix failure to detect DAT corruption in btree and direct mappings Ryusuke Konishi
@ 2024-03-13 10:58   ` Ryusuke Konishi
  1 sibling, 0 replies; 3+ messages in thread
From: Ryusuke Konishi @ 2024-03-13 10:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: syzbot, syzkaller-bugs, linux-nilfs, linux-kernel

Fix a bug where nilfs_get_block() returns a successful status when
searching and inserting the specified block both fail inconsistently.
If this inconsistent behavior is not due to a previously fixed bug,
then an unexpected race is occurring, so return a temporary error
-EAGAIN instead.

This prevents callers such as __block_write_begin_int() from
requesting a read into a buffer that is not mapped, which would cause
the BUG_ON check for the BH_Mapped flag in submit_bh_wbc() to fail.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Fixes: 1f5abe7e7dbc ("nilfs2: replace BUG_ON and BUG calls triggerable from ioctl")
Cc: stable@vger.kernel.org
---
 fs/nilfs2/inode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 9c334c722fc1..5a888b2c1803 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -112,7 +112,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
 					   "%s (ino=%lu): a race condition while inserting a data block at offset=%llu",
 					   __func__, inode->i_ino,
 					   (unsigned long long)blkoff);
-				err = 0;
+				err = -EAGAIN;
 			}
 			nilfs_transaction_abort(inode->i_sb);
 			goto out;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-03-13 10:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <0000000000002df264056a35b16b@google.com>
2024-03-13 10:58 ` [PATCH 0/2] nilfs2: fix kernel bug at submit_bh_wbc() Ryusuke Konishi
2024-03-13 10:58   ` [PATCH 1/2] nilfs2: fix failure to detect DAT corruption in btree and direct mappings Ryusuke Konishi
2024-03-13 10:58   ` [PATCH 2/2] nilfs2: prevent kernel bug at submit_bh_wbc() Ryusuke Konishi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox