commit 4fdcfab5b553 ("jffs2: fix use-after-free on symlink traversal") move free operation of f->target to jffs2_i_callback(). But when destroy an jffs2 inode in iget_locked(), jffs2_inode_info was not initialized. which results in destroy_inode() calling jffs2_i_callback() to kfree the uninitialized pointer f->target and then BUG_ON. So move the initialization from jffs2_init_inode_info() to jffs2_alloc_inode(). The stack likes following: [19700101000004]kernel BUG at mm/slub.c:3824! [19700101000004]Internal error: Oops - BUG: 0 [#1] SMP ARM [19700101000004]CPU: 2 PID: 9 Comm: rcuos/0 Tainted: P O 4.4.185 #1 [19700101000004]PC is at kfree+0xfc/0x264 [19700101000004]LR is at jffs2_i_callback+0x10/0x28 [jffs2] ...... [20191219102226][<ffffff80083630a4>] kfree+0xd4/0x2ac [20191219102226][<ffffff80008a0ae4>] jffs2_i_callback+0x24/0x40 [jffs2] [20191219102226][<ffffff800828a908>] rcu_process_callbacks+0x524/0x61c [20191219102226][<ffffff8008229cf8>] __do_softirq+0x1e0/0x3bc [20191219102226][<ffffff800822a19c>] irq_exit+0xa0/0x124 [20191219102226][<ffffff800825074c>] msa_irq_exit+0x138/0x1c4 [20191219102226][<ffffff800827aaf8>] __handle_domain_irq+0xf0/0x1a4 [20191219102226][<ffffff8008200944>] gic_handle_irq+0xac/0x140 Reported-by: Guohua Zhong <zhongguohua1@xxxxxxxxxx> Signed-off-by: Huaijie Yi <yihuaijie@xxxxxxxxxx> Signed-off-by: zhangyi (F) <yi.zhang@xxxxxxxxxx> Signed-off-by: chenjie <chenjie6@xxxxxxxxxx> Signed-off-by: fangxinwei <fangxinwei@xxxxxxxxxx> --- fs/jffs2/os-linux.h | 1 - fs/jffs2/super.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index ef1cfa61549e..625c4da3246d 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -54,7 +54,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) f->fragtree = RB_ROOT; f->metadata = NULL; f->dents = NULL; - f->target = NULL; f->flags = 0; f->usercompr = 0; } diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 0e6406c4f362..d76ed98057a1 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -42,6 +42,8 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb) f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); if (!f) return NULL; + f->target = NULL; + return &f->vfs_inode; } -- 2.12.3 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/