[PATCH] jffs2: fix double-free of f->target in jffs2_alloc_inode()

Deepanshu Kartikey <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.drivers.mtd
Message-ID <[email protected]>
jffs2_alloc_inode() does not initialize f->target before returning
the new inode. It is normally cleared later by
jffs2_init_inode_info(), called from jffs2_iget(), but that runs
only after alloc_inode() has already returned successfully.

If inode_init_always() fails in between, alloc_inode() calls
->free_inode() directly on the half-initialized inode.
jffs2_free_inode() then does kfree(f->target) on whatever stale
value was left in the reused slab object, which can be a pointer
that was already freed, causing a double-free.

Initialize f->target to NULL in jffs2_alloc_inode() to close this
window, and clear it in jffs2_free_inode() after freeing it so a
reused or re-freed object can never carry a dangling pointer.

Fixes: 4fdcfab5b553 ("jffs2: fix use-after-free on symlink traversal")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=675e84fdf3dde67b4946
Signed-off-by: Deepanshu Kartikey <[email protected]>
---
 fs/jffs2/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 81396a092ba8..30d753d4c263 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -42,6 +42,7 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb)
 	f = alloc_inode_sb(sb, jffs2_inode_cachep, GFP_KERNEL);
 	if (!f)
 		return NULL;
+	f->target = NULL;
 	return &f->vfs_inode;
 }
 
@@ -50,6 +51,7 @@ static void jffs2_free_inode(struct inode *inode)
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 
 	kfree(f->target);
+	f->target = NULL;
 	kmem_cache_free(jffs2_inode_cachep, f);
 }
 
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.