From 13b215a9e657808414a2159b0dec90f1c31ebe05 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Tue, 4 Jan 2022 15:35:17 +0100 Subject: ext4: don't use kfree() on rcu protected pointer sbi->s_qf_names During ext4 mount api rework the commit e6e268cb6822 ("ext4: move quota configuration out of handle_mount_opt()") introduced a bug where we would kfree(sbi->s_qf_names[i]) before assigning the new quota name in ext4_apply_quota_options(). This is wrong because we're using kfree() on rcu prointer that could be simultaneously accessed from ext4_show_quota_options() during remount. Fix it by using rcu_replace_pointer() to replace the old qname with the new one and then kfree_rcu() the old quota name. Also use get_qf_name() instead of sbi->s_qf_names in strcmp() to silence the sparse warning. Fixes: e6e268cb6822 ("ext4: move quota configuration out of handle_mount_opt()") Reported-by: kernel test robot Signed-off-by: Lukas Czerner Link: https://lore.kernel.org/r/20220104143518.134465-1-lczerner@redhat.com Signed-off-by: Theodore Ts'o --- fs/ext4/super.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'fs/ext4/super.c') diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1b55f234e006..72e4dfc9acaf 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2636,8 +2636,10 @@ static void ext4_apply_quota_options(struct fs_context *fc, qname = ctx->s_qf_names[i]; /* May be NULL */ ctx->s_qf_names[i] = NULL; - kfree(sbi->s_qf_names[i]); - rcu_assign_pointer(sbi->s_qf_names[i], qname); + qname = rcu_replace_pointer(sbi->s_qf_names[i], qname, + lockdep_is_held(&sb->s_umount)); + if (qname) + kfree_rcu(qname); set_opt(sb, QUOTA); } } @@ -2691,7 +2693,7 @@ static int ext4_check_quota_consistency(struct fs_context *fc, goto err_jquota_change; if (sbi->s_qf_names[i] && ctx->s_qf_names[i] && - strcmp(sbi->s_qf_names[i], + strcmp(get_qf_name(sb, sbi, i), ctx->s_qf_names[i]) != 0) goto err_jquota_specified; } -- cgit v1.2.3