Re: [PATCH] nilfs2: fix use-after-free bug in nilfs_mdt_destroy()

From: Ryusuke Konishi
Date: Mon Aug 15 2022 - 20:28:31 EST


On Tue, Aug 16, 2022 at 3:27 AM Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote:
>
> On Tue, Aug 16, 2022 at 02:51:14AM +0900, Ryusuke Konishi wrote:
> > In alloc_inode(), inode_init_always() could return -ENOMEM if
> > security_inode_alloc() fails. If this happens for nilfs2,
> > nilfs_free_inode() is called without initializing inode->i_private and
> > nilfs_free_inode() wrongly calls nilfs_mdt_destroy(), which frees
> > uninitialized inode->i_private and can trigger a crash.
> >
> > Fix this bug by initializing inode->i_private in nilfs_alloc_inode().
> >
> > Link: https://lkml.kernel.org/r/CAFcO6XOcf1Jj2SeGt=jJV59wmhESeSKpfR0omdFRq+J9nD1vfQ@xxxxxxxxxxxxxx
> > Link: https://lkml.kernel.org/r/20211011030956.2459172-1-mudongliangabcd@xxxxxxxxx
> > Reported-by: butt3rflyh4ck <butterflyhuangxx@xxxxxxxxx>
> > Reported-by: Hao Sun <sunhao.th@xxxxxxxxx>
> > Reported-by: Jiacheng Xu <stitch@xxxxxxxxxx>
> > Reported-by: Mudong Liang <mudongliangabcd@xxxxxxxxx>
> > Signed-off-by: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxx>
> > Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> > ---
> > fs/nilfs2/super.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
> > index ba108f915391..aca5614f1b44 100644
> > --- a/fs/nilfs2/super.c
> > +++ b/fs/nilfs2/super.c
> > @@ -159,6 +159,7 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
> > ii->i_cno = 0;
> > ii->i_assoc_inode = NULL;
> > ii->i_bmap = &ii->i_bmap_data;
> > + ii->vfs_inode.i_private = NULL;
> > return &ii->vfs_inode;
> > }
>
> FWIW, I think it's better to deal with that in inode_init_always(), but
> not just moving ->i_private initialization up - we ought to move
> security_inode_alloc() to the very end. No sense playing whack-a-mole
> with further possible bugs of that sort...

Yes, I agree it's better if security_inode_alloc() is moved to the end as
possible in the sense of avoiding similar issues.
But, would that vfs change be safe to backport to stable trees?

It looks like the error handling for security_inode_alloc() is in the
middle of inode_init_always() for a very long time..

If you want to see the impact of the vfs change, I think it's one way
to apply this one in advance. Or if you want to fix it in one step,
I think it's good too. How do you feel about this ?

Thanks,
Ryusuke Konishi