| From 5353b7012932e086bd517182c05c60cef6207f4b Mon Sep 17 00:00:00 2001 |
| From: Al Viro <viro@zeniv.linux.org.uk> |
| Date: Tue, 26 Mar 2019 01:38:58 +0000 |
| Subject: ceph: fix use-after-free on symlink traversal |
| |
| [ Upstream commit daf5cc27eed99afdea8d96e71b89ba41f5406ef6 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> |
| --- |
| fs/ceph/inode.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c |
| index a1492bdc6d03..f2b722f0df5d 100644 |
| --- a/fs/ceph/inode.c |
| +++ b/fs/ceph/inode.c |
| @@ -520,6 +520,7 @@ static void ceph_i_callback(struct rcu_head *head) |
| struct inode *inode = container_of(head, struct inode, i_rcu); |
| struct ceph_inode_info *ci = ceph_inode(inode); |
| |
| + kfree(ci->i_symlink); |
| kmem_cache_free(ceph_inode_cachep, ci); |
| } |
| |
| @@ -551,7 +552,6 @@ void ceph_destroy_inode(struct inode *inode) |
| ceph_put_snap_realm(mdsc, realm); |
| } |
| |
| - kfree(ci->i_symlink); |
| while ((n = rb_first(&ci->i_fragtree)) != NULL) { |
| frag = rb_entry(n, struct ceph_inode_frag, node); |
| rb_erase(n, &ci->i_fragtree); |
| -- |
| 2.19.1 |
| |