Skip to content

Commit f240d3a

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: do more sanity check on inode
There are several issues in sanity_check_inode(): - The code looks not clean, it checks extra_attr related condition dispersively. - It missed to check i_extra_isize w/ lower boundary - It missed to check feature dependency: prjquota, inode_chksum, inode_crtime, compression features rely on extra_attr feature. - It's not necessary to check i_extra_isize due to it will only be assigned to non-zero value if f2fs_has_extra_attr() is true in do_read_inode(). Fix them all in this patch. Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 64ee916 commit f240d3a

2 files changed

Lines changed: 67 additions & 35 deletions

File tree

fs/f2fs/f2fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,6 +3417,8 @@ static inline int get_inline_xattr_addrs(struct inode *inode)
34173417
((is_inode_flag_set(i, FI_ACL_MODE)) ? \
34183418
(F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
34193419

3420+
#define F2FS_MIN_EXTRA_ATTR_SIZE (sizeof(__le32))
3421+
34203422
#define F2FS_TOTAL_EXTRA_ATTR_SIZE \
34213423
(offsetof(struct f2fs_inode, i_extra_end) - \
34223424
offsetof(struct f2fs_inode, i_extra_isize)) \

fs/f2fs/inode.c

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -301,41 +301,77 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
301301
return false;
302302
}
303303

304-
if (f2fs_sb_has_flexible_inline_xattr(sbi)
305-
&& !f2fs_has_extra_attr(inode)) {
304+
if (f2fs_has_extra_attr(inode)) {
305+
if (!f2fs_sb_has_extra_attr(sbi)) {
306+
set_sbi_flag(sbi, SBI_NEED_FSCK);
307+
f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off",
308+
__func__, inode->i_ino);
309+
return false;
310+
}
311+
if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE ||
312+
fi->i_extra_isize < F2FS_MIN_EXTRA_ATTR_SIZE ||
313+
fi->i_extra_isize % sizeof(__le32)) {
314+
set_sbi_flag(sbi, SBI_NEED_FSCK);
315+
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, max: %zu",
316+
__func__, inode->i_ino, fi->i_extra_isize,
317+
F2FS_TOTAL_EXTRA_ATTR_SIZE);
318+
return false;
319+
}
320+
if (f2fs_sb_has_flexible_inline_xattr(sbi) &&
321+
f2fs_has_inline_xattr(inode) &&
322+
(!fi->i_inline_xattr_size ||
323+
fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
324+
set_sbi_flag(sbi, SBI_NEED_FSCK);
325+
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu",
326+
__func__, inode->i_ino, fi->i_inline_xattr_size,
327+
MAX_INLINE_XATTR_SIZE);
328+
return false;
329+
}
330+
if (f2fs_sb_has_compression(sbi) &&
331+
fi->i_flags & F2FS_COMPR_FL &&
332+
F2FS_FITS_IN_INODE(ri, fi->i_extra_isize,
333+
i_compress_flag)) {
334+
if (!sanity_check_compress_inode(inode, ri))
335+
return false;
336+
}
337+
} else if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
306338
set_sbi_flag(sbi, SBI_NEED_FSCK);
307339
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, run fsck to fix.",
308340
__func__, inode->i_ino);
309341
return false;
310342
}
311343

312-
if (f2fs_has_extra_attr(inode) &&
313-
!f2fs_sb_has_extra_attr(sbi)) {
314-
set_sbi_flag(sbi, SBI_NEED_FSCK);
315-
f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off",
316-
__func__, inode->i_ino);
317-
return false;
318-
}
319-
320-
if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE ||
321-
fi->i_extra_isize % sizeof(__le32)) {
322-
set_sbi_flag(sbi, SBI_NEED_FSCK);
323-
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, max: %zu",
324-
__func__, inode->i_ino, fi->i_extra_isize,
325-
F2FS_TOTAL_EXTRA_ATTR_SIZE);
326-
return false;
327-
}
328-
329-
if (f2fs_has_extra_attr(inode) &&
330-
f2fs_sb_has_flexible_inline_xattr(sbi) &&
331-
f2fs_has_inline_xattr(inode) &&
332-
(!fi->i_inline_xattr_size ||
333-
fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
334-
set_sbi_flag(sbi, SBI_NEED_FSCK);
335-
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu",
336-
__func__, inode->i_ino, fi->i_inline_xattr_size,
337-
MAX_INLINE_XATTR_SIZE);
338-
return false;
344+
if (!f2fs_sb_has_extra_attr(sbi)) {
345+
if (f2fs_sb_has_project_quota(sbi)) {
346+
set_sbi_flag(sbi, SBI_NEED_FSCK);
347+
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
348+
__func__, inode->i_ino, F2FS_FEATURE_PRJQUOTA);
349+
return false;
350+
}
351+
if (f2fs_sb_has_inode_chksum(sbi)) {
352+
set_sbi_flag(sbi, SBI_NEED_FSCK);
353+
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
354+
__func__, inode->i_ino, F2FS_FEATURE_INODE_CHKSUM);
355+
return false;
356+
}
357+
if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
358+
set_sbi_flag(sbi, SBI_NEED_FSCK);
359+
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
360+
__func__, inode->i_ino, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR);
361+
return false;
362+
}
363+
if (f2fs_sb_has_inode_crtime(sbi)) {
364+
set_sbi_flag(sbi, SBI_NEED_FSCK);
365+
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
366+
__func__, inode->i_ino, F2FS_FEATURE_INODE_CRTIME);
367+
return false;
368+
}
369+
if (f2fs_sb_has_compression(sbi)) {
370+
set_sbi_flag(sbi, SBI_NEED_FSCK);
371+
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
372+
__func__, inode->i_ino, F2FS_FEATURE_COMPRESSION);
373+
return false;
374+
}
339375
}
340376

341377
if (f2fs_sanity_check_inline_data(inode)) {
@@ -359,12 +395,6 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
359395
return false;
360396
}
361397

362-
if (f2fs_has_extra_attr(inode) && f2fs_sb_has_compression(sbi) &&
363-
fi->i_flags & F2FS_COMPR_FL &&
364-
F2FS_FITS_IN_INODE(ri, fi->i_extra_isize,
365-
i_compress_flag))
366-
return sanity_check_compress_inode(inode, ri);
367-
368398
return true;
369399
}
370400

0 commit comments

Comments
 (0)