Linux-ext4 Archive on lore.kernel.org
 help / color / Atom feed
* [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup()
@ 2021-03-22 15:24 Zhang Yi
  2021-03-22 17:25 ` Jan Kara
  0 siblings, 1 reply; 5+ messages in thread
From: Zhang Yi @ 2021-03-22 15:24 UTC (permalink / raw)
  To: Jan Kara; +Cc: Theodore Y. Ts'o, Ext4 Developers List, yangerkun

Hi, Jan.

We find a use after free problem when CONFIG_QUOTA is enabled, the detail of
this problem is below.

mount_bdev()
	ext4_fill_super()
		sb->s_root = d_make_root(root);
		ext4_orphan_cleanup()
			sb->s_flags |= SB_ACTIVE; <--- 1. mark sb active
			ext4_orphan_get()
			ext4_truncate()
				ext4_block_truncate_page()
					mark_buffer_dirty <--- 2. dirty inode
			iput()
				iput_final  <--- 3. put into lru list
		ext4_mark_recovery_complete  <--- 4. failed and return error
		sb->s_root = NULL;
	deactivate_locked_super()
		kill_block_super()
			generic_shutdown_super()
				<--- 5. did not evict_inodes
		put_super()
			__put_super()
				<--- 6. put super block

Because of the truncated inodes was dirty and will write them back later, it
will trigger use after free problem. Now the question is why we need to set
SB_ACTIVE bit when enable CONFIG_QUOTA below?

  #ifdef CONFIG_QUOTA
          /* Needed for iput() to work correctly and not trash data */
          sb->s_flags |= SB_ACTIVE;

This code was merged long long ago in v2.6.6, IIUC, it may not affect
the quota statistics it we evict inode directly in the last iput.
In order to slove this UAF problem, I'm not sure is there any side effect
if we just remove this code, or remove SB_ACTIVE and call evict_inodes()
in the error path of ext4_fill_super().

Could you give some suggestions?

Thanks,
Yi.

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

* Re: [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup()
  2021-03-22 15:24 [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup() Zhang Yi
@ 2021-03-22 17:25 ` Jan Kara
  2021-03-29  9:20   ` Zhang Yi
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Kara @ 2021-03-22 17:25 UTC (permalink / raw)
  To: Zhang Yi; +Cc: Jan Kara, Theodore Y. Ts'o, Ext4 Developers List, yangerkun

Hi!

On Mon 22-03-21 23:24:23, Zhang Yi wrote:
> We find a use after free problem when CONFIG_QUOTA is enabled, the detail of
> this problem is below.
> 
> mount_bdev()
> 	ext4_fill_super()
> 		sb->s_root = d_make_root(root);
> 		ext4_orphan_cleanup()
> 			sb->s_flags |= SB_ACTIVE; <--- 1. mark sb active
> 			ext4_orphan_get()
> 			ext4_truncate()
> 				ext4_block_truncate_page()
> 					mark_buffer_dirty <--- 2. dirty inode
> 			iput()
> 				iput_final  <--- 3. put into lru list
> 		ext4_mark_recovery_complete  <--- 4. failed and return error
> 		sb->s_root = NULL;
> 	deactivate_locked_super()
> 		kill_block_super()
> 			generic_shutdown_super()
> 				<--- 5. did not evict_inodes
> 		put_super()
> 			__put_super()
> 				<--- 6. put super block
> 
> Because of the truncated inodes was dirty and will write them back later, it
> will trigger use after free problem. Now the question is why we need to set
> SB_ACTIVE bit when enable CONFIG_QUOTA below?
> 
>   #ifdef CONFIG_QUOTA
>           /* Needed for iput() to work correctly and not trash data */
>           sb->s_flags |= SB_ACTIVE;
> 
> This code was merged long long ago in v2.6.6, IIUC, it may not affect
> the quota statistics it we evict inode directly in the last iput.
> In order to slove this UAF problem, I'm not sure is there any side effect
> if we just remove this code, or remove SB_ACTIVE and call evict_inodes()
> in the error path of ext4_fill_super().
> 
> Could you give some suggestions?

That's a very good question. I do remember that I've added this code back
then because otherwise orphan cleanup was loosing updates to quota files.
But you're right that now I don't see how that could be happening and it
would be nice if we could get rid of this hack (and even better if it also
fixes the problem you've found). I guess I'll just try and test this change
with various quota configurations to see whether something still breaks or
not. Thanks report!

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* Re: [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup()
  2021-03-22 17:25 ` Jan Kara
@ 2021-03-29  9:20   ` Zhang Yi
  2021-03-30 15:02     ` Jan Kara
  0 siblings, 1 reply; 5+ messages in thread
From: Zhang Yi @ 2021-03-29  9:20 UTC (permalink / raw)
  To: Jan Kara
  Cc: Theodore Y. Ts'o, Ext4 Developers List, yangerkun, linfeilong

On 2021/3/23 1:25, Jan Kara wrote:
> Hi!
> 
> On Mon 22-03-21 23:24:23, Zhang Yi wrote:
>> We find a use after free problem when CONFIG_QUOTA is enabled, the detail of
>> this problem is below.
>>
>> mount_bdev()
>> 	ext4_fill_super()
>> 		sb->s_root = d_make_root(root);
>> 		ext4_orphan_cleanup()
>> 			sb->s_flags |= SB_ACTIVE; <--- 1. mark sb active
>> 			ext4_orphan_get()
>> 			ext4_truncate()
>> 				ext4_block_truncate_page()
>> 					mark_buffer_dirty <--- 2. dirty inode
>> 			iput()
>> 				iput_final  <--- 3. put into lru list
>> 		ext4_mark_recovery_complete  <--- 4. failed and return error
>> 		sb->s_root = NULL;
>> 	deactivate_locked_super()
>> 		kill_block_super()
>> 			generic_shutdown_super()
>> 				<--- 5. did not evict_inodes
>> 		put_super()
>> 			__put_super()
>> 				<--- 6. put super block
>>
>> Because of the truncated inodes was dirty and will write them back later, it
>> will trigger use after free problem. Now the question is why we need to set
>> SB_ACTIVE bit when enable CONFIG_QUOTA below?
>>
>>   #ifdef CONFIG_QUOTA
>>           /* Needed for iput() to work correctly and not trash data */
>>           sb->s_flags |= SB_ACTIVE;
>>
>> This code was merged long long ago in v2.6.6, IIUC, it may not affect
>> the quota statistics it we evict inode directly in the last iput.
>> In order to slove this UAF problem, I'm not sure is there any side effect
>> if we just remove this code, or remove SB_ACTIVE and call evict_inodes()
>> in the error path of ext4_fill_super().
>>
>> Could you give some suggestions?
> 
> That's a very good question. I do remember that I've added this code back
> then because otherwise orphan cleanup was loosing updates to quota files.
> But you're right that now I don't see how that could be happening and it
> would be nice if we could get rid of this hack (and even better if it also
> fixes the problem you've found). I guess I'll just try and test this change
> with various quota configurations to see whether something still breaks or
> not. Thanks report!
> 

Thanks for taking time to look at this, is this change OK under your various
quota test cases?

Thanks,
Yi.

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

* Re: [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup()
  2021-03-29  9:20   ` Zhang Yi
@ 2021-03-30 15:02     ` Jan Kara
  2021-03-31  3:11       ` Zhang Yi
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Kara @ 2021-03-30 15:02 UTC (permalink / raw)
  To: Zhang Yi
  Cc: Jan Kara, Theodore Y. Ts'o, Ext4 Developers List, yangerkun,
	linfeilong

On Mon 29-03-21 17:20:35, Zhang Yi wrote:
> On 2021/3/23 1:25, Jan Kara wrote:
> > Hi!
> > 
> > On Mon 22-03-21 23:24:23, Zhang Yi wrote:
> >> We find a use after free problem when CONFIG_QUOTA is enabled, the detail of
> >> this problem is below.
> >>
> >> mount_bdev()
> >> 	ext4_fill_super()
> >> 		sb->s_root = d_make_root(root);
> >> 		ext4_orphan_cleanup()
> >> 			sb->s_flags |= SB_ACTIVE; <--- 1. mark sb active
> >> 			ext4_orphan_get()
> >> 			ext4_truncate()
> >> 				ext4_block_truncate_page()
> >> 					mark_buffer_dirty <--- 2. dirty inode
> >> 			iput()
> >> 				iput_final  <--- 3. put into lru list
> >> 		ext4_mark_recovery_complete  <--- 4. failed and return error
> >> 		sb->s_root = NULL;
> >> 	deactivate_locked_super()
> >> 		kill_block_super()
> >> 			generic_shutdown_super()
> >> 				<--- 5. did not evict_inodes
> >> 		put_super()
> >> 			__put_super()
> >> 				<--- 6. put super block
> >>
> >> Because of the truncated inodes was dirty and will write them back later, it
> >> will trigger use after free problem. Now the question is why we need to set
> >> SB_ACTIVE bit when enable CONFIG_QUOTA below?
> >>
> >>   #ifdef CONFIG_QUOTA
> >>           /* Needed for iput() to work correctly and not trash data */
> >>           sb->s_flags |= SB_ACTIVE;
> >>
> >> This code was merged long long ago in v2.6.6, IIUC, it may not affect
> >> the quota statistics it we evict inode directly in the last iput.
> >> In order to slove this UAF problem, I'm not sure is there any side effect
> >> if we just remove this code, or remove SB_ACTIVE and call evict_inodes()
> >> in the error path of ext4_fill_super().
> >>
> >> Could you give some suggestions?
> > 
> > That's a very good question. I do remember that I've added this code back
> > then because otherwise orphan cleanup was loosing updates to quota files.
> > But you're right that now I don't see how that could be happening and it
> > would be nice if we could get rid of this hack (and even better if it also
> > fixes the problem you've found). I guess I'll just try and test this change
> > with various quota configurations to see whether something still breaks or
> > not. Thanks report!
> > 
> 
> Thanks for taking time to look at this, is this change OK under your various
> quota test cases?

Yes, I did tests both with journalled quotas and with ext4 quota feature
and the quota accounting was correct after orphan recovery. So just
removing the SB_ACTIVE setting is fine AFAICT. Will you send a patch or
should I do it?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* Re: [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup()
  2021-03-30 15:02     ` Jan Kara
@ 2021-03-31  3:11       ` Zhang Yi
  0 siblings, 0 replies; 5+ messages in thread
From: Zhang Yi @ 2021-03-31  3:11 UTC (permalink / raw)
  To: Jan Kara
  Cc: Theodore Y. Ts'o, Ext4 Developers List, yangerkun, linfeilong

On 2021/3/30 23:02, Jan Kara wrote:
> On Mon 29-03-21 17:20:35, Zhang Yi wrote:
>> On 2021/3/23 1:25, Jan Kara wrote:
>>> Hi!
>>>
>>> On Mon 22-03-21 23:24:23, Zhang Yi wrote:
>>>> We find a use after free problem when CONFIG_QUOTA is enabled, the detail of
>>>> this problem is below.
>>>>
>>>> mount_bdev()
>>>> 	ext4_fill_super()
>>>> 		sb->s_root = d_make_root(root);
>>>> 		ext4_orphan_cleanup()
>>>> 			sb->s_flags |= SB_ACTIVE; <--- 1. mark sb active
>>>> 			ext4_orphan_get()
>>>> 			ext4_truncate()
>>>> 				ext4_block_truncate_page()
>>>> 					mark_buffer_dirty <--- 2. dirty inode
>>>> 			iput()
>>>> 				iput_final  <--- 3. put into lru list
>>>> 		ext4_mark_recovery_complete  <--- 4. failed and return error
>>>> 		sb->s_root = NULL;
>>>> 	deactivate_locked_super()
>>>> 		kill_block_super()
>>>> 			generic_shutdown_super()
>>>> 				<--- 5. did not evict_inodes
>>>> 		put_super()
>>>> 			__put_super()
>>>> 				<--- 6. put super block
>>>>
>>>> Because of the truncated inodes was dirty and will write them back later, it
>>>> will trigger use after free problem. Now the question is why we need to set
>>>> SB_ACTIVE bit when enable CONFIG_QUOTA below?
>>>>
>>>>   #ifdef CONFIG_QUOTA
>>>>           /* Needed for iput() to work correctly and not trash data */
>>>>           sb->s_flags |= SB_ACTIVE;
>>>>
>>>> This code was merged long long ago in v2.6.6, IIUC, it may not affect
>>>> the quota statistics it we evict inode directly in the last iput.
>>>> In order to slove this UAF problem, I'm not sure is there any side effect
>>>> if we just remove this code, or remove SB_ACTIVE and call evict_inodes()
>>>> in the error path of ext4_fill_super().
>>>>
>>>> Could you give some suggestions?
>>>
>>> That's a very good question. I do remember that I've added this code back
>>> then because otherwise orphan cleanup was loosing updates to quota files.
>>> But you're right that now I don't see how that could be happening and it
>>> would be nice if we could get rid of this hack (and even better if it also
>>> fixes the problem you've found). I guess I'll just try and test this change
>>> with various quota configurations to see whether something still breaks or
>>> not. Thanks report!
>>>
>>
>> Thanks for taking time to look at this, is this change OK under your various
>> quota test cases?
> 
> Yes, I did tests both with journalled quotas and with ext4 quota feature
> and the quota accounting was correct after orphan recovery. So just
> removing the SB_ACTIVE setting is fine AFAICT. Will you send a patch or
> should I do it?
> 

Thanks for testing this change, I will send a patch.

Yi.

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

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-22 15:24 [BUG && Question] question of SB_ACTIVE flag in ext4_orphan_cleanup() Zhang Yi
2021-03-22 17:25 ` Jan Kara
2021-03-29  9:20   ` Zhang Yi
2021-03-30 15:02     ` Jan Kara
2021-03-31  3:11       ` Zhang Yi

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