Re: [PATCH] jffs2: fix UAF problem

From: Joakim Tjernlund
Date: Tue Jul 07 2020 - 10:05:05 EST


Maintainer ping ?

Jocke

On Wed, 2020-06-24 at 18:59 +0000, Joakim Tjernlund wrote:
>
> Nice find, I just came across a deadlock wrt GC and rmdir,
> hopefully this is he fix.
>
> This needs to go to stable too, sooner rather than later.
>
> ÂJocke
>
> On Fri, 2020-06-19 at 17:06 +0800, Zhe Li wrote:
> >
> > The log of UAF problem is listed below.
> > BUG: KASAN: use-after-free in jffs2_rmdir+0xa4/0x1cc [jffs2] at addr c1f165fc
> > Read of size 4 by task rm/8283
> > =============================================================================
> > BUG kmalloc-32 (Tainted: P B O ): kasan: bad access detected
> > -----------------------------------------------------------------------------
> >
> > INFO: Allocated in 0xbbbbbbbb age=3054364 cpu=0 pid=0
> > ÂÂÂÂÂÂÂÂ0xb0bba6ef
> > ÂÂÂÂÂÂÂÂjffs2_write_dirent+0x11c/0x9c8 [jffs2]
> > ÂÂÂÂÂÂÂÂ__slab_alloc.isra.21.constprop.25+0x2c/0x44
> > ÂÂÂÂÂÂÂÂ__kmalloc+0x1dc/0x370
> > ÂÂÂÂÂÂÂÂjffs2_write_dirent+0x11c/0x9c8 [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_do_unlink+0x328/0x5fc [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_rmdir+0x110/0x1cc [jffs2]
> > ÂÂÂÂÂÂÂÂvfs_rmdir+0x180/0x268
> > ÂÂÂÂÂÂÂÂdo_rmdir+0x2cc/0x300
> > ÂÂÂÂÂÂÂÂret_from_syscall+0x0/0x3c
> > INFO: Freed in 0x205b age=3054364 cpu=0 pid=0
> > ÂÂÂÂÂÂÂÂ0x2e9173
> > ÂÂÂÂÂÂÂÂjffs2_add_fd_to_list+0x138/0x1dc [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_add_fd_to_list+0x138/0x1dc [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_garbage_collect_dirent.isra.3+0x21c/0x288 [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_garbage_collect_live+0x16bc/0x1800 [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_garbage_collect_pass+0x678/0x11d4 [jffs2]
> > ÂÂÂÂÂÂÂÂjffs2_garbage_collect_thread+0x1e8/0x3b0 [jffs2]
> > ÂÂÂÂÂÂÂÂkthread+0x1a8/0x1b0
> > ÂÂÂÂÂÂÂÂret_from_kernel_thread+0x5c/0x64
> > Call Trace:
> > [c17ddd20] [c02452d4] kasan_report.part.0+0x298/0x72c (unreliable)
> > [c17ddda0] [d2509680] jffs2_rmdir+0xa4/0x1cc [jffs2]
> > [c17dddd0] [c026da04] vfs_rmdir+0x180/0x268
> > [c17dde00] [c026f4e4] do_rmdir+0x2cc/0x300
> > [c17ddf40] [c001a658] ret_from_syscall+0x0/0x3c
> >
> > The root cause is that we don't get "jffs2_inode_info.sem" before
> > we scan list "jffs2_inode_info.dents" in function jffs2_rmdir.
> > This patch add codes to get "jffs2_inode_info.sem" before we scan
> > "jffs2_inode_info.dents" to slove the UAF problem.
> >
> > Signed-off-by: Zhe Li <lizhe67@xxxxxxxxxx>
> > ---
> > Âfs/jffs2/dir.c | 6 +++++-
> > Â1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
> > index f20cff1..7764937 100644
> > --- a/fs/jffs2/dir.c
> > +++ b/fs/jffs2/dir.c
> > @@ -590,10 +590,14 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
> > ÂÂÂÂÂÂÂÂint ret;
> > ÂÂÂÂÂÂÂÂuint32_t now = JFFS2_NOW();
> >
> > + mutex_lock(&f->sem);
> > ÂÂÂÂÂÂÂÂfor (fd = f->dents ; fd; fd = fd->next) {
> > - if (fd->ino)
> > + if (fd->ino) {
> > + mutex_unlock(&f->sem);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturn -ENOTEMPTY;
> > + }
> > ÂÂÂÂÂÂÂÂ}
> > + mutex_unlock(&f->sem);
> >
> > ÂÂÂÂÂÂÂÂret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂdentry->d_name.len, f, now);
> > --
> > 2.7.4
> >
> >
> >