fs/ext4/super.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
From: Ye Bin <yebin10@huawei.com>
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>
---
fs/ext4/super.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b31db521d6bf..dc3907dff13a 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;
--
2.31.1
On Thu, 19 Jan 2023 09:37:11 +0800, Ye Bin wrote: > From: Ye Bin <yebin10@huawei.com> > > 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); > > [...] Applied, thanks! [1/1] ext4: init error handle resource before init group descriptors commit: 2806abcc97829d49172632db81deac9119641b78 Best regards, -- Theodore Ts'o <tytso@mit.edu>
On Thu 19-01-23 09:37:11, Ye Bin wrote: > From: Ye Bin <yebin10@huawei.com> > > 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. Looks good to me. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > fs/ext4/super.c | 19 +++++++------------ > 1 file changed, 7 insertions(+), 12 deletions(-) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index b31db521d6bf..dc3907dff13a 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; > -- > 2.31.1 > -- Jan Kara <jack@suse.com> SUSE Labs, CR
© 2016 - 2025 Red Hat, Inc.