]> 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 07:17:19 +0000 (09:17 +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 386303dca382e636fa9aab5d547f343e2e5058a1..4f390be717234b2f0794eb063c8569bf82b476b9 100644 (file)
@@ -1429,11 +1429,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 0bbc31d1085709bc7878d4a78bdb700419a3e642..d1be5991bb6624a8fd16f89aa21fcd382a9f656f 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)