Linux-ext4 Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] ext4: do not set SB_ACTIVE in ext4_orphan_cleanup()
@ 2021-03-31  3:31 Zhang Yi
  2021-03-31  9:59 ` Jan Kara
  0 siblings, 1 reply; 3+ messages in thread
From: Zhang Yi @ 2021-03-31  3:31 UTC (permalink / raw)
  To: linux-ext4; +Cc: tytso, adilger.kernel, jack, yi.zhang

When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due
to some error happens behind ext4_orphan_cleanup(), it will end up
triggering a after free issue of super_block. The problem is that
ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is
enabled, after we cleanup the truncated inodes, the last iput() will put
them into the lru list, and these inodes' pages may probably dirty and
will be write back by the writeback thread, so it could be raced by
freeing super_block in the error path of mount_bdev().

After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it
was used to ensure updating the quota file properly, but evict inode and
trash data immediately in the last iput does not affect the quotafile,
so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by
just remove the SB_ACTIVE setting.

[1] https://lore.kernel.org/linux-ext4/99cce8ca-e4a0-7301-840f-2ace67c551f3@huawei.com/T/#m04990cfbc4f44592421736b504afcc346b2a7c00

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Tested-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/super.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b9693680463a..2a33c53b57d8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3023,9 +3023,6 @@ static void ext4_orphan_cleanup(struct super_block *sb,
 		sb->s_flags &= ~SB_RDONLY;
 	}
 #ifdef CONFIG_QUOTA
-	/* Needed for iput() to work correctly and not trash data */
-	sb->s_flags |= SB_ACTIVE;
-
 	/*
 	 * Turn on quotas which were not enabled for read-only mounts if
 	 * filesystem has quota feature, so that they are updated correctly.
-- 
2.25.4


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ext4: do not set SB_ACTIVE in ext4_orphan_cleanup()
  2021-03-31  3:31 [PATCH] ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() Zhang Yi
@ 2021-03-31  9:59 ` Jan Kara
  2021-04-09 16:43   ` Theodore Ts'o
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Kara @ 2021-03-31  9:59 UTC (permalink / raw)
  To: Zhang Yi; +Cc: linux-ext4, tytso, adilger.kernel, jack

On Wed 31-03-21 11:31:38, Zhang Yi wrote:
> When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due
> to some error happens behind ext4_orphan_cleanup(), it will end up
> triggering a after free issue of super_block. The problem is that
> ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is
> enabled, after we cleanup the truncated inodes, the last iput() will put
> them into the lru list, and these inodes' pages may probably dirty and
> will be write back by the writeback thread, so it could be raced by
> freeing super_block in the error path of mount_bdev().
> 
> After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it
> was used to ensure updating the quota file properly, but evict inode and
> trash data immediately in the last iput does not affect the quotafile,
> so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by
> just remove the SB_ACTIVE setting.

Thanks for the patch. Let me rephrase the changelog a little:

When CONFIG_QUOTA is enabled and if we later fail to finish mounting the
filesystem due to some error after ext4_orphan_cleanup(), we may hit use
after free issues. The problem is that ext4_orphan_cleanup() sets SB_ACTIVE
flag and so inodes processed during the orphan cleanup are put to the
superblock's LRU list instead of being immediately destroyed. However the
path handling error recovery after failed ->fill_super() call does not
destroy inodes attached to the superblock and so they are left active in
memory while the superblock is freed.

Originally, SB_ACTIVE setting was added so that updated quota information
is not destroyed when we drop quota inode references after orphan cleanup.
However VFS does not purge dirty inode pages without SB_ACTIVE flag for many
years already. So just remove the hack with setting SB_ACTIVE flag from
ext4_orphan_cleanup().

Also feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> 
> [1] https://lore.kernel.org/linux-ext4/99cce8ca-e4a0-7301-840f-2ace67c551f3@huawei.com/T/#m04990cfbc4f44592421736b504afcc346b2a7c00
> 
> Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
> Tested-by: Jan Kara <jack@suse.cz>
> ---
>  fs/ext4/super.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index b9693680463a..2a33c53b57d8 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -3023,9 +3023,6 @@ static void ext4_orphan_cleanup(struct super_block *sb,
>  		sb->s_flags &= ~SB_RDONLY;
>  	}
>  #ifdef CONFIG_QUOTA
> -	/* Needed for iput() to work correctly and not trash data */
> -	sb->s_flags |= SB_ACTIVE;
> -
>  	/*
>  	 * Turn on quotas which were not enabled for read-only mounts if
>  	 * filesystem has quota feature, so that they are updated correctly.
> -- 
> 2.25.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ext4: do not set SB_ACTIVE in ext4_orphan_cleanup()
  2021-03-31  9:59 ` Jan Kara
@ 2021-04-09 16:43   ` Theodore Ts'o
  0 siblings, 0 replies; 3+ messages in thread
From: Theodore Ts'o @ 2021-04-09 16:43 UTC (permalink / raw)
  To: Jan Kara; +Cc: Zhang Yi, linux-ext4, adilger.kernel

On Wed, Mar 31, 2021 at 11:59:20AM +0200, Jan Kara wrote:
> On Wed 31-03-21 11:31:38, Zhang Yi wrote:
> > When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due
> > to some error happens behind ext4_orphan_cleanup(), it will end up
> > triggering a after free issue of super_block. The problem is that
> > ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is
> > enabled, after we cleanup the truncated inodes, the last iput() will put
> > them into the lru list, and these inodes' pages may probably dirty and
> > will be write back by the writeback thread, so it could be raced by
> > freeing super_block in the error path of mount_bdev().
> > 
> > After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it
> > was used to ensure updating the quota file properly, but evict inode and
> > trash data immediately in the last iput does not affect the quotafile,
> > so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by
> > just remove the SB_ACTIVE setting.
> 
> Thanks for the patch. Let me rephrase the changelog a little:
> 
> When CONFIG_QUOTA is enabled and if we later fail to finish mounting the
> filesystem due to some error after ext4_orphan_cleanup(), we may hit use
> after free issues. The problem is that ext4_orphan_cleanup() sets SB_ACTIVE
> flag and so inodes processed during the orphan cleanup are put to the
> superblock's LRU list instead of being immediately destroyed. However the
> path handling error recovery after failed ->fill_super() call does not
> destroy inodes attached to the superblock and so they are left active in
> memory while the superblock is freed.
> 
> Originally, SB_ACTIVE setting was added so that updated quota information
> is not destroyed when we drop quota inode references after orphan cleanup.
> However VFS does not purge dirty inode pages without SB_ACTIVE flag for many
> years already. So just remove the hack with setting SB_ACTIVE flag from
> ext4_orphan_cleanup().
> 
> Also feel free to add:
> 
> Reviewed-by: Jan Kara <jack@suse.cz>
> 
> 								Honza

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-31  3:31 [PATCH] ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() Zhang Yi
2021-03-31  9:59 ` Jan Kara
2021-04-09 16:43   ` Theodore Ts'o

Linux-ext4 Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-ext4/0 linux-ext4/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-ext4 linux-ext4/ https://lore.kernel.org/linux-ext4 \
		linux-ext4@vger.kernel.org
	public-inbox-index linux-ext4

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-ext4


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git