Message ID | 20200619090635.58548-1-lizhe67@huawei.com |
---|---|
State | Accepted |
Headers | show |
Series | jffs2: fix UAF problem | expand |
Reviewed-by: Hou Tao <houtao1@huawei.com> On 2020/6/19 17:06, 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@huawei.com> > --- > 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); >
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@huawei.com> > --- > 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 > > > > ______________________________________________________ > Linux MTD discussion mailing list > https://nam03.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.infradead.org%2Fmailman%2Flistinfo%2Flinux-mtd%2F&data=02%7C01%7Cjoakim.tjernlund%40infinera.com%7C339a1184745b4c76bdf908d8143043b2%7C285643de5f5b4b03a1530ae2dc8aaf77%7C1%7C1%7C637281544815697582&sdata=jKo97fc3j6jVcjVpS2exm0sDL%2BWr6DqkTe6jqe8G9t8%3D&reserved=0
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@huawei.com> > > --- > > 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 > > > > > >
On Tue, Jul 7, 2020 at 4:08 PM Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote: > > Maintainer ping ? Whoops. Applied for fixes.
On Tue, 2020-07-07 at 18:30 +0200, Richard Weinberger wrote: > CAUTION: This email originated from outside of the organization. Do > not click links or open attachments unless you recognize the sender > and know the content is safe. > > > On Tue, Jul 7, 2020 at 4:08 PM Joakim Tjernlund > <Joakim.Tjernlund@infinera.com> wrote: > > > > Maintainer ping ? > > Whoops. Applied for fixes. Did you queue for stable too? This bug has been there since day one for jffs2
On Mon, Jul 13, 2020 at 11:51 PM Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote: > Did you queue for stable too? > This bug has been there since day one for jffs2 It will. I just had no chance to re-create my setup after the infradead.org meltdown. :-)
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);
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@huawei.com> --- fs/jffs2/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)