diff mbox series

jffs2: fix kfree uninitialized pointer in jffs2_i_callback

Message ID 20191220070724.27660-1-yihuaijie@huawei.com
State New
Delegated to: David Woodhouse
Headers show
Series jffs2: fix kfree uninitialized pointer in jffs2_i_callback | expand

Commit Message

Huaijie Yi Dec. 20, 2019, 7:07 a.m. UTC
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@huawei.com>
Signed-off-by: Huaijie Yi <yihuaijie@huawei.com>
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: chenjie <chenjie6@huawei.com>
Signed-off-by: fangxinwei <fangxinwei@huawei.com>
---
 fs/jffs2/os-linux.h | 1 -
 fs/jffs2/super.c    | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)
diff mbox series

Patch

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;
 }