diff options
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/dir.c | 12 | ||||
-rw-r--r-- | fs/f2fs/node.c | 3 | ||||
-rw-r--r-- | fs/f2fs/super.c | 8 |
3 files changed, 19 insertions, 4 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4abefd841b6c..ff519f7a8784 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -817,6 +817,17 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, de_name.name = d->filename[bit_pos]; de_name.len = le16_to_cpu(de->name_len); + /* check memory boundary before moving forward */ + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); + if (unlikely(bit_pos > d->max || + le16_to_cpu(de->name_len) > F2FS_NAME_LEN)) { + f2fs_msg(F2FS_I_SB(d->inode)->sb, KERN_WARNING, + "%s: corrupted namelen=%d, run fsck to fix.", + __func__, le16_to_cpu(de->name_len)); + set_sbi_flag(F2FS_I_SB(d->inode)->sb->s_fs_info, SBI_NEED_FSCK); + return -EINVAL; + } + if (f2fs_encrypted_inode(d->inode)) { int save_len = fstr->len; int err; @@ -835,7 +846,6 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, le32_to_cpu(de->ino), d_type)) return 1; - bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); ctx->pos = start_pos + bit_pos; } return 0; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index e7b8e2b35e22..f8006f62c546 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -2011,6 +2011,9 @@ static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) if (unlikely(nid >= nm_i->max_nid)) nid = 0; + if (unlikely(nid % NAT_ENTRY_PER_BLOCK)) + nid = NAT_BLOCK_OFFSET(nid) * NAT_ENTRY_PER_BLOCK; + /* Enough entries */ if (nm_i->nid_cnt[FREE_NID_LIST] >= NAT_ENTRY_PER_BLOCK) return; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2d021a33914a..990339c538b0 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -782,6 +782,9 @@ static void f2fs_put_super(struct super_block *sb) struct f2fs_sb_info *sbi = F2FS_SB(sb); int i; + /* unregister procfs/sysfs entries in advance to avoid race case */ + f2fs_unregister_sysfs(sbi); + f2fs_quota_off_umount(sb); /* prevent remaining shrinker jobs */ @@ -834,8 +837,6 @@ static void f2fs_put_super(struct super_block *sb) kfree(sbi->ckpt); - f2fs_unregister_sysfs(sbi); - sb->s_fs_info = NULL; if (sbi->s_chksum_driver) crypto_free_shash(sbi->s_chksum_driver); @@ -918,7 +919,8 @@ static int f2fs_statfs_project(struct super_block *sb, limit >>= sb->s_blocksize_bits; if (limit && buf->f_blocks > limit) { - curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits; + curblock = (dquot->dq_dqb.dqb_curspace + + dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; buf->f_blocks = limit; buf->f_bfree = buf->f_bavail = (buf->f_blocks > curblock) ? |