diff mbox series

[f2fs-dev] f2fs: fix to detect inconsistent nat entry during truncation

Message ID 20240322145955.2959257-1-chao@kernel.org (mailing list archive)
State Accepted
Commit 92c556ed6318e13c16746495a8d4513129eb9b0f
Headers show
Series [f2fs-dev] f2fs: fix to detect inconsistent nat entry during truncation | expand

Commit Message

Chao Yu March 22, 2024, 2:59 p.m. UTC
As Roman Smirnov reported as below:

"
There is a possible bug in f2fs_truncate_inode_blocks():

    if (err < 0 && err != -ENOENT)
    			goto fail;
        ...
        offset[1] = 0;
        offset[0]++;
        nofs += err;

If err = -ENOENT then nofs will sum with an error code,
which is strange behaviour. Also if nofs < ENOENT this will
cause an overflow. err will be equal to -ENOENT with the
following call stack:

truncate_nodes()
  f2fs_get_node_page()
     __get_node_page()
        read_node_page()
"

If nat is corrupted, truncate_nodes() may return -ENOENT, and
f2fs_truncate_inode_blocks() doesn't handle such error correctly,
fix it.

Reported-by: Roman Smirnov <r.smirnov@omp.ru>
Closes: https://lore.kernel.org/linux-f2fs-devel/085b27fd2b364a3c8c3a9ca77363e246@omp.ru
Signed-off-by: Chao Yu <chao@kernel.org>
---
 fs/f2fs/node.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

patchwork-bot+f2fs@kernel.org April 14, 2024, 3:32 p.m. UTC | #1
Hello:

This patch was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:

On Fri, 22 Mar 2024 22:59:55 +0800 you wrote:
> As Roman Smirnov reported as below:
> 
> "
> There is a possible bug in f2fs_truncate_inode_blocks():
> 
>     if (err < 0 && err != -ENOENT)
>     			goto fail;
>         ...
>         offset[1] = 0;
>         offset[0]++;
>         nofs += err;
> 
> [...]

Here is the summary with links:
  - [f2fs-dev] f2fs: fix to detect inconsistent nat entry during truncation
    https://git.kernel.org/jaegeuk/f2fs/c/92c556ed6318

You are awesome, thank you!
diff mbox series

Patch

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index b3de6d6cdb02..bb57bbaff7b4 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1187,7 +1187,17 @@  int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from)
 		default:
 			BUG();
 		}
-		if (err < 0 && err != -ENOENT)
+		if (err == -ENOENT) {
+			set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK);
+			f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+			f2fs_err_ratelimited(sbi,
+				"truncate node fail, ino:%lu, nid:%u, "
+				"offset[0]:%d, offset[1]:%d, nofs:%d",
+				inode->i_ino, dn.nid, offset[0],
+				offset[1], nofs);
+			err = 0;
+		}
+		if (err < 0)
 			goto fail;
 		if (offset[1] == 0 &&
 				ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) {