]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
jffs2: fix use-after-free on symlink traversal
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 26 Mar 2019 01:39:50 +0000 (01:39 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2019 17:45:01 +0000 (19:45 +0200)
[ Upstream commit 4fdcfab5b5537c21891e22e65996d4d0dd8ab4ca ]

free the symlink body after the same RCU delay we have for freeing the
struct inode itself, so that traversal during RCU pathwalk wouldn't step
into freed memory.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/jffs2/readinode.c
fs/jffs2/super.c

index bfebbf13698c0e0d255e20f5ebf26de7fd6b5845..5b52ea41b84fa9ba057467390336a2ff5cc78224 100644 (file)
@@ -1414,11 +1414,6 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
 
        jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
 
-       if (f->target) {
-               kfree(f->target);
-               f->target = NULL;
-       }
-
        fds = f->dents;
        while(fds) {
                fd = fds;
index 023e7f32ee1be017c46190067c15de7679e7d9a7..9fc297df8c758bc1868d696ab50c3c6f2bb7758a 100644 (file)
@@ -47,7 +47,10 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb)
 static void jffs2_i_callback(struct rcu_head *head)
 {
        struct inode *inode = container_of(head, struct inode, i_rcu);
-       kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));
+       struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+
+       kfree(f->target);
+       kmem_cache_free(jffs2_inode_cachep, f);
 }
 
 static void jffs2_destroy_inode(struct inode *inode)