On Jun 29, 2021, at 8:36 AM, Ye Bin wrote: > > Now sbi->s_mmp_tsk is created with kthread_run, then kmmpd maybe > already running and even exit as exception. Even though we set > sbi->s_mmp_tsk with NULL before kmmpd kthread exit, but > "sbi->s_mmp_tsk=kthread_run(XX)" may set after set with NULL. > mount kmmpd > | | > |-call kthread_run | > | |-kmmpd runing > | |-kmmpd exit sbi->s_mmp_tsk=NULL > | | > |-kthread_run return | > | and set sbi->s_mmp_tsk | > | | > |-then we get wild ptr"sbi->s_mmp_tsk" and later trigger UAF > > This patch is base on previous "ext4: Fix use-after-free about sbi->s_mmp_tsk". > Previous patch ensure kmmpd kthread exit by itself will set sbi->s_mmp_tsk with > NULL. We can create kthread first, and then wakeup kmmpd kthread later. > > Signed-off-by: Ye Bin Please note minor typo in the patch subject, should be "use-after-free". Reviewed-by: Andreas Dilger > --- > fs/ext4/mmp.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c > index fc18a8c205c7..6ec1ea182cc0 100644 > --- a/fs/ext4/mmp.c > +++ b/fs/ext4/mmp.c > @@ -394,16 +394,18 @@ int ext4_multi_mount_protect(struct super_block *sb, > /* > * Start a kernel thread to update the MMP block periodically. > */ > - EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%.*s", > - (int)sizeof(mmp->mmp_bdevname), > - bdevname(bh->b_bdev, > - mmp->mmp_bdevname)); > + EXT4_SB(sb)->s_mmp_tsk = kthread_create(kmmpd, sb, "kmmpd-%.*s", > + (int)sizeof(mmp->mmp_bdevname), > + bdevname(bh->b_bdev, > + mmp->mmp_bdevname)); > + > if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) { > EXT4_SB(sb)->s_mmp_tsk = NULL; > ext4_warning(sb, "Unable to create kmmpd thread for %s.", > sb->s_id); > goto failed; > } > + wake_up_process(EXT4_SB(sb)->s_mmp_tsk); > > return 0; > > -- > 2.31.1 > Cheers, Andreas