diff options
author | Ye Bin <yebin10@huawei.com> | 2023-01-19 09:37:11 +0800 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2023-02-25 15:39:07 -0500 |
commit | 172e344e6f82dc266cb65a69f4bed03428ea8a05 (patch) | |
tree | 0efc24cc009218d63a86f42ab1ecb25b6b746d9a /fs/ext4 | |
parent | 0f7bfd6f8164be32dbbdf36aa1e5d00485c53cd7 (diff) |
ext4: init error handle resource before init group descriptors
Now, 's_err_report' timer is init after ext4_group_desc_init() when fill
super. Theoretically, ext4_group_desc_init() may access to error handle
as follows:
__ext4_fill_super
ext4_group_desc_init
ext4_check_descriptors
ext4_get_group_desc
ext4_error
ext4_handle_error
ext4_commit_super
ext4_update_super
if (!es->s_error_count)
mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ);
--> Accessing Uninitialized Variables
timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
Maybe above issue is just theoretical, as ext4_check_descriptors() didn't
judge 'gpd' which get from ext4_get_group_desc(), if access to error handle
ext4_get_group_desc() will return NULL, then will trigger null-ptr-deref in
ext4_check_descriptors().
However, from the perspective of pure code, it is better to initialize
resource that may need to be used first.
Signed-off-by: Ye Bin <yebin10@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230119013711.86680-1-yebin@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 45bcfd35e559..143e0b573ca5 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4738,7 +4738,6 @@ static int ext4_group_desc_init(struct super_block *sb, struct ext4_sb_info *sbi = EXT4_SB(sb); unsigned int db_count; ext4_fsblk_t block; - int ret; int i; db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / @@ -4778,8 +4777,7 @@ static int ext4_group_desc_init(struct super_block *sb, ext4_msg(sb, KERN_ERR, "can't read group descriptor %d", i); sbi->s_gdb_count = i; - ret = PTR_ERR(bh); - goto out; + return PTR_ERR(bh); } rcu_read_lock(); rcu_dereference(sbi->s_group_desc)[i] = bh; @@ -4788,13 +4786,10 @@ static int ext4_group_desc_init(struct super_block *sb, sbi->s_gdb_count = db_count; if (!ext4_check_descriptors(sb, logical_sb_block, first_not_zeroed)) { ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); - ret = -EFSCORRUPTED; - goto out; + return -EFSCORRUPTED; } + return 0; -out: - ext4_group_desc_free(sbi); - return ret; } static int ext4_load_and_init_journal(struct super_block *sb, @@ -5220,14 +5215,14 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) if (ext4_geometry_check(sb, es)) goto failed_mount; - err = ext4_group_desc_init(sb, es, logical_sb_block, &first_not_zeroed); - if (err) - goto failed_mount; - timer_setup(&sbi->s_err_report, print_daily_error_info, 0); spin_lock_init(&sbi->s_error_lock); INIT_WORK(&sbi->s_error_work, flush_stashed_error_work); + err = ext4_group_desc_init(sb, es, logical_sb_block, &first_not_zeroed); + if (err) + goto failed_mount3; + /* Register extent status tree shrinker */ if (ext4_es_register_shrinker(sbi)) goto failed_mount3; |