* [PATCH] fsck.f2fs: add more sanity check for superblock
@ 2019-06-13 8:10 ` Chao Yu
0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu @ 2019-06-13 8:10 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: jaegeuk, seulbae
Add more sanity check logic for superblock like we did in kernel side.
This fixes bug reported by Seulbae Kim from bugzilla.
https://bugzilla.kernel.org/show_bug.cgi?id=203861
Reproted-by: Seulbae Kim <seulbae@gatech.edu>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
fsck/mount.c | 96 ++++++++++++++++++++++++++++++++++++++++++-----
include/f2fs_fs.h | 2 +
2 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/fsck/mount.c b/fsck/mount.c
index 8d5d5cf..f295642 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -601,38 +601,117 @@ static int verify_sb_chksum(struct f2fs_super_block *sb)
int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
{
unsigned int blocksize;
+ unsigned int segment_count, segs_per_sec, secs_per_zone;
+ unsigned int total_sections, blocks_per_seg;
if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) &&
verify_sb_chksum(sb))
return -1;
- if (F2FS_SUPER_MAGIC != get_sb(magic))
+ if (F2FS_SUPER_MAGIC != get_sb(magic)) {
+ MSG(0, "Magic Mismatch, valid(0x%x) - read(0x%x)\n",
+ F2FS_SUPER_MAGIC, get_sb(magic));
return -1;
+ }
- if (F2FS_BLKSIZE != PAGE_CACHE_SIZE)
+ if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) {
+ MSG(0, "Invalid page_cache_size (%d), supports only 4KB\n",
+ PAGE_CACHE_SIZE);
return -1;
+ }
blocksize = 1 << get_sb(log_blocksize);
- if (F2FS_BLKSIZE != blocksize)
+ if (F2FS_BLKSIZE != blocksize) {
+ MSG(0, "Invalid blocksize (%u), supports only 4KB\n",
+ blocksize);
return -1;
+ }
/* check log blocks per segment */
- if (get_sb(log_blocks_per_seg) != 9)
+ if (get_sb(log_blocks_per_seg) != 9) {
+ MSG(0, "Invalid log blocks per segment (%u)\n",
+ get_sb(log_blocks_per_seg));
return -1;
+ }
/* Currently, support 512/1024/2048/4096 bytes sector size */
if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
- get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
+ get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE) {
+ MSG(0, "Invalid log sectorsize (%u)\n", get_sb(log_sectorsize));
return -1;
+ }
if (get_sb(log_sectors_per_block) + get_sb(log_sectorsize) !=
- F2FS_MAX_LOG_SECTOR_SIZE)
+ F2FS_MAX_LOG_SECTOR_SIZE) {
+ MSG(0, "Invalid log sectors per block(%u) log sectorsize(%u)\n",
+ get_sb(log_sectors_per_block),
+ get_sb(log_sectorsize));
+ return -1;
+ }
+
+ segment_count = get_sb(segment_count);
+ segs_per_sec = get_sb(segs_per_sec);
+ secs_per_zone = get_sb(secs_per_zone);
+ total_sections = get_sb(section_count);
+
+ /* blocks_per_seg should be 512, given the above check */
+ blocks_per_seg = 1 << get_sb(log_blocks_per_seg);
+
+ if (segment_count > F2FS_MAX_SEGMENT ||
+ segment_count < F2FS_MIN_SEGMENTS) {
+ MSG(0, "\tInvalid segment count (%u)\n", segment_count);
return -1;
+ }
+
+ if (total_sections > segment_count ||
+ total_sections < F2FS_MIN_SEGMENTS ||
+ segs_per_sec > segment_count || !segs_per_sec) {
+ MSG(0, "\tInvalid segment/section count (%u, %u x %u)\n",
+ segment_count, total_sections, segs_per_sec);
+ return 1;
+ }
+
+ if ((segment_count / segs_per_sec) < total_sections) {
+ MSG(0, "Small segment_count (%u < %u * %u)\n",
+ segment_count, segs_per_sec, total_sections);
+ return 1;
+ }
+
+ if (segment_count > (get_sb(block_count) >> 9)) {
+ MSG(0, "Wrong segment_count / block_count (%u > %llu)\n",
+ segment_count, get_sb(block_count));
+ return 1;
+ }
+
+ if (secs_per_zone > total_sections || !secs_per_zone) {
+ MSG(0, "Wrong secs_per_zone / total_sections (%u, %u)\n",
+ secs_per_zone, total_sections);
+ return 1;
+ }
+ if (get_sb(extension_count) > F2FS_MAX_EXTENSION ||
+ sb->hot_ext_count > F2FS_MAX_EXTENSION ||
+ get_sb(extension_count) +
+ sb->hot_ext_count > F2FS_MAX_EXTENSION) {
+ MSG(0, "Corrupted extension count (%u + %u > %u)\n",
+ get_sb(extension_count),
+ sb->hot_ext_count,
+ F2FS_MAX_EXTENSION);
+ return 1;
+ }
+
+ if (get_sb(cp_payload) > (blocks_per_seg - F2FS_CP_PACKS)) {
+ MSG(0, "Insane cp_payload (%u > %u)\n",
+ get_sb(cp_payload), blocks_per_seg - F2FS_CP_PACKS);
+ return 1;
+ }
/* check reserved ino info */
if (get_sb(node_ino) != 1 || get_sb(meta_ino) != 2 ||
- get_sb(root_ino) != 3)
+ get_sb(root_ino) != 3) {
+ MSG(0, "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)\n",
+ get_sb(node_ino), get_sb(meta_ino), get_sb(root_ino));
return -1;
+ }
/* Check zoned block device feature */
if (c.devices[0].zoned_model == F2FS_ZONED_HM &&
@@ -641,9 +720,6 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
return -1;
}
- if (get_sb(segment_count) > F2FS_MAX_SEGMENT)
- return -1;
-
if (sanity_check_area_boundary(sb, sb_addr))
return -1;
return 0;
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 1890975..9f1e86c 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -662,6 +662,8 @@ struct f2fs_super_block {
#define CP_ORPHAN_PRESENT_FLAG 0x00000002
#define CP_UMOUNT_FLAG 0x00000001
+#define F2FS_CP_PACKS 2 /* # of checkpoint packs */
+
struct f2fs_checkpoint {
__le64 checkpoint_ver; /* checkpoint block version number */
__le64 user_block_count; /* # of user blocks */
--
2.18.0.rc1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [f2fs-dev] [PATCH] fsck.f2fs: add more sanity check for superblock
@ 2019-06-13 8:10 ` Chao Yu
0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu @ 2019-06-13 8:10 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: jaegeuk, seulbae
Add more sanity check logic for superblock like we did in kernel side.
This fixes bug reported by Seulbae Kim from bugzilla.
https://bugzilla.kernel.org/show_bug.cgi?id=203861
Reproted-by: Seulbae Kim <seulbae@gatech.edu>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
fsck/mount.c | 96 ++++++++++++++++++++++++++++++++++++++++++-----
include/f2fs_fs.h | 2 +
2 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/fsck/mount.c b/fsck/mount.c
index 8d5d5cf..f295642 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -601,38 +601,117 @@ static int verify_sb_chksum(struct f2fs_super_block *sb)
int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
{
unsigned int blocksize;
+ unsigned int segment_count, segs_per_sec, secs_per_zone;
+ unsigned int total_sections, blocks_per_seg;
if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) &&
verify_sb_chksum(sb))
return -1;
- if (F2FS_SUPER_MAGIC != get_sb(magic))
+ if (F2FS_SUPER_MAGIC != get_sb(magic)) {
+ MSG(0, "Magic Mismatch, valid(0x%x) - read(0x%x)\n",
+ F2FS_SUPER_MAGIC, get_sb(magic));
return -1;
+ }
- if (F2FS_BLKSIZE != PAGE_CACHE_SIZE)
+ if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) {
+ MSG(0, "Invalid page_cache_size (%d), supports only 4KB\n",
+ PAGE_CACHE_SIZE);
return -1;
+ }
blocksize = 1 << get_sb(log_blocksize);
- if (F2FS_BLKSIZE != blocksize)
+ if (F2FS_BLKSIZE != blocksize) {
+ MSG(0, "Invalid blocksize (%u), supports only 4KB\n",
+ blocksize);
return -1;
+ }
/* check log blocks per segment */
- if (get_sb(log_blocks_per_seg) != 9)
+ if (get_sb(log_blocks_per_seg) != 9) {
+ MSG(0, "Invalid log blocks per segment (%u)\n",
+ get_sb(log_blocks_per_seg));
return -1;
+ }
/* Currently, support 512/1024/2048/4096 bytes sector size */
if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
- get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
+ get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE) {
+ MSG(0, "Invalid log sectorsize (%u)\n", get_sb(log_sectorsize));
return -1;
+ }
if (get_sb(log_sectors_per_block) + get_sb(log_sectorsize) !=
- F2FS_MAX_LOG_SECTOR_SIZE)
+ F2FS_MAX_LOG_SECTOR_SIZE) {
+ MSG(0, "Invalid log sectors per block(%u) log sectorsize(%u)\n",
+ get_sb(log_sectors_per_block),
+ get_sb(log_sectorsize));
+ return -1;
+ }
+
+ segment_count = get_sb(segment_count);
+ segs_per_sec = get_sb(segs_per_sec);
+ secs_per_zone = get_sb(secs_per_zone);
+ total_sections = get_sb(section_count);
+
+ /* blocks_per_seg should be 512, given the above check */
+ blocks_per_seg = 1 << get_sb(log_blocks_per_seg);
+
+ if (segment_count > F2FS_MAX_SEGMENT ||
+ segment_count < F2FS_MIN_SEGMENTS) {
+ MSG(0, "\tInvalid segment count (%u)\n", segment_count);
return -1;
+ }
+
+ if (total_sections > segment_count ||
+ total_sections < F2FS_MIN_SEGMENTS ||
+ segs_per_sec > segment_count || !segs_per_sec) {
+ MSG(0, "\tInvalid segment/section count (%u, %u x %u)\n",
+ segment_count, total_sections, segs_per_sec);
+ return 1;
+ }
+
+ if ((segment_count / segs_per_sec) < total_sections) {
+ MSG(0, "Small segment_count (%u < %u * %u)\n",
+ segment_count, segs_per_sec, total_sections);
+ return 1;
+ }
+
+ if (segment_count > (get_sb(block_count) >> 9)) {
+ MSG(0, "Wrong segment_count / block_count (%u > %llu)\n",
+ segment_count, get_sb(block_count));
+ return 1;
+ }
+
+ if (secs_per_zone > total_sections || !secs_per_zone) {
+ MSG(0, "Wrong secs_per_zone / total_sections (%u, %u)\n",
+ secs_per_zone, total_sections);
+ return 1;
+ }
+ if (get_sb(extension_count) > F2FS_MAX_EXTENSION ||
+ sb->hot_ext_count > F2FS_MAX_EXTENSION ||
+ get_sb(extension_count) +
+ sb->hot_ext_count > F2FS_MAX_EXTENSION) {
+ MSG(0, "Corrupted extension count (%u + %u > %u)\n",
+ get_sb(extension_count),
+ sb->hot_ext_count,
+ F2FS_MAX_EXTENSION);
+ return 1;
+ }
+
+ if (get_sb(cp_payload) > (blocks_per_seg - F2FS_CP_PACKS)) {
+ MSG(0, "Insane cp_payload (%u > %u)\n",
+ get_sb(cp_payload), blocks_per_seg - F2FS_CP_PACKS);
+ return 1;
+ }
/* check reserved ino info */
if (get_sb(node_ino) != 1 || get_sb(meta_ino) != 2 ||
- get_sb(root_ino) != 3)
+ get_sb(root_ino) != 3) {
+ MSG(0, "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)\n",
+ get_sb(node_ino), get_sb(meta_ino), get_sb(root_ino));
return -1;
+ }
/* Check zoned block device feature */
if (c.devices[0].zoned_model == F2FS_ZONED_HM &&
@@ -641,9 +720,6 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
return -1;
}
- if (get_sb(segment_count) > F2FS_MAX_SEGMENT)
- return -1;
-
if (sanity_check_area_boundary(sb, sb_addr))
return -1;
return 0;
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 1890975..9f1e86c 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -662,6 +662,8 @@ struct f2fs_super_block {
#define CP_ORPHAN_PRESENT_FLAG 0x00000002
#define CP_UMOUNT_FLAG 0x00000001
+#define F2FS_CP_PACKS 2 /* # of checkpoint packs */
+
struct f2fs_checkpoint {
__le64 checkpoint_ver; /* checkpoint block version number */
__le64 user_block_count; /* # of user blocks */
--
2.18.0.rc1
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-06-13 8:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-13 8:10 [PATCH] fsck.f2fs: add more sanity check for superblock Chao Yu
2019-06-13 8:10 ` [f2fs-dev] " Chao Yu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.