Hi, Christoph On 2021/4/15 22:52, Christoph Hellwig wrote: > On Wed, Apr 14, 2021 at 09:47:37PM +0800, Zhang Yi wrote: >> There still exist a use after free issue when accessing the journal >> structure and ext4_sb_info structure on freeing bdev buffers in >> bdev_try_to_free_page(). The problem is bdev_try_to_free_page() could be >> raced by ext4_put_super(), it dose freeing sb->s_fs_info and >> sbi->s_journal while release page progress are still accessing them. >> So it could end up trigger use-after-free or NULL pointer dereference. > > I think the right fix is to not even call into ->bdev_try_to_free_page > unless the superblock is active. > . > Thanks for your suggestions. Now, we use already use "if (bdev->bd_super)" to prevent call into ->bdev_try_to_free_page unless the super is alive, and the problem is bd_super becomes NULL concurrently after this check. So, IIUC, I think it's the same to switch to check the superblock is active or not. The acvive flag also could becomes inactive (raced by umount) after we call into bdev_try_to_free_page(). In order to close this race, One solution is introduce a lock to synchronize the active state between kill_block_super() and blkdev_releasepage(), but the releasing page process have to try to acquire this lock in blkdev_releasepage() for each page, and the umount process still need to wait until the page release if some one invoke into ->bdev_try_to_free_page(). I think this solution may affect performace and is not a good way. Think about it in depth, use percpu refcount seems have the smallest performance effect on blkdev_releasepage(). If you don't like the refcount, maybe we could add synchronize_rcu_expedited() in ext4_put_super(), it also could prevent this race. Any suggestions? Thanks, Yi.