aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2019-03-25 21:38:58 -0400
committerIlya Dryomov <idryomov@gmail.com>2019-03-27 14:00:37 -0400
commitdaf5cc27eed99afdea8d96e71b89ba41f5406ef6 (patch)
tree388c0f95be488d43a4576b871657e38dfc7740e2
parent187df76325af5d9e12ae9daec1510307797e54f0 (diff)
ceph: fix use-after-free on symlink traversal
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> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/inode.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index e3346628efe2..2d61ddda9bf5 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -524,6 +524,7 @@ static void ceph_i_callback(struct rcu_head *head)
524 struct inode *inode = container_of(head, struct inode, i_rcu); 524 struct inode *inode = container_of(head, struct inode, i_rcu);
525 struct ceph_inode_info *ci = ceph_inode(inode); 525 struct ceph_inode_info *ci = ceph_inode(inode);
526 526
527 kfree(ci->i_symlink);
527 kmem_cache_free(ceph_inode_cachep, ci); 528 kmem_cache_free(ceph_inode_cachep, ci);
528} 529}
529 530
@@ -566,7 +567,6 @@ void ceph_destroy_inode(struct inode *inode)
566 } 567 }
567 } 568 }
568 569
569 kfree(ci->i_symlink);
570 while ((n = rb_first(&ci->i_fragtree)) != NULL) { 570 while ((n = rb_first(&ci->i_fragtree)) != NULL) {
571 frag = rb_entry(n, struct ceph_inode_frag, node); 571 frag = rb_entry(n, struct ceph_inode_frag, node);
572 rb_erase(n, &ci->i_fragtree); 572 rb_erase(n, &ci->i_fragtree);