Skip to content

Commit 9337ed5

Browse files
chaseyugregkh
authored andcommitted
f2fs: fix to detect potential corrupted nid in free_nid_list
[ Upstream commit 8fc6056 ] As reported, on-disk footer.ino and footer.nid is the same and out-of-range, let's add sanity check on f2fs_alloc_nid() to detect any potential corruption in free_nid_list. Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Signed-off-by: Robert Garcia <rob_garcia@163.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f99165e commit 9337ed5

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

fs/f2fs/node.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,17 @@ static struct kmem_cache *free_nid_slab;
2727
static struct kmem_cache *nat_entry_set_slab;
2828
static struct kmem_cache *fsync_node_entry_slab;
2929

30+
static inline bool is_invalid_nid(struct f2fs_sb_info *sbi, nid_t nid)
31+
{
32+
return nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid;
33+
}
34+
3035
/*
3136
* Check whether the given nid is within node id range.
3237
*/
3338
int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
3439
{
35-
if (unlikely(nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid)) {
40+
if (unlikely(is_invalid_nid(sbi, nid))) {
3641
set_sbi_flag(sbi, SBI_NEED_FSCK);
3742
f2fs_warn(sbi, "%s: out-of-range nid=%x, run fsck to fix.",
3843
__func__, nid);
@@ -2603,6 +2608,16 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
26032608
f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list));
26042609
i = list_first_entry(&nm_i->free_nid_list,
26052610
struct free_nid, list);
2611+
2612+
if (unlikely(is_invalid_nid(sbi, i->nid))) {
2613+
spin_unlock(&nm_i->nid_list_lock);
2614+
f2fs_err(sbi, "Corrupted nid %u in free_nid_list",
2615+
i->nid);
2616+
f2fs_stop_checkpoint(sbi, false,
2617+
STOP_CP_REASON_CORRUPTED_NID);
2618+
return false;
2619+
}
2620+
26062621
*nid = i->nid;
26072622

26082623
__move_free_nid(sbi, i, FREE_NID, PREALLOC_NID);

include/linux/f2fs_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ enum stop_cp_reason {
7777
STOP_CP_REASON_UPDATE_INODE,
7878
STOP_CP_REASON_FLUSH_FAIL,
7979
STOP_CP_REASON_NO_SEGMENT,
80+
STOP_CP_REASON_CORRUPTED_NID,
8081
STOP_CP_REASON_MAX,
8182
};
8283

0 commit comments

Comments
 (0)