summaryrefslogtreecommitdiff
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-06-22 16:26:34 +0800
committerIlya Dryomov <idryomov@gmail.com>2017-07-07 17:25:13 +0200
commit62a65f36d016fff32179acdbfcb8b2d8d9e54757 (patch)
tree4e78b5d157227e97ecfcb75e1a49d0b60ad37941 /fs/ceph
parent1684dd03e9f59212775cafa50ea77b9ef5b263db (diff)
downloadlwn-62a65f36d016fff32179acdbfcb8b2d8d9e54757.tar.gz
lwn-62a65f36d016fff32179acdbfcb8b2d8d9e54757.zip
ceph: avoid invalid memory dereference in the middle of umount
extra_mon_dispatch() and debugfs' foo_show functions dereference fsc->mdsc. we should clean up fsc->client->extra_mon_dispatch and debugfs before destroying fsc->mds. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/mds_client.c4
-rw-r--r--fs/ceph/super.c6
2 files changed, 6 insertions, 4 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 0c05df44cc6c..666a9f274832 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -3769,13 +3769,13 @@ static void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
{
struct ceph_mds_client *mdsc = fsc->mdsc;
-
dout("mdsc_destroy %p\n", mdsc);
- ceph_mdsc_stop(mdsc);
/* flush out any connection work with references to us */
ceph_msgr_flush();
+ ceph_mdsc_stop(mdsc);
+
fsc->mdsc = NULL;
kfree(mdsc);
dout("mdsc_destroy %p done\n", mdsc);
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 8d7918ce694a..14e78dd52ef9 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -636,8 +636,6 @@ static void destroy_fs_client(struct ceph_fs_client *fsc)
destroy_mount_options(fsc->mount_options);
- ceph_fs_debugfs_cleanup(fsc);
-
ceph_destroy_client(fsc->client);
kfree(fsc);
@@ -1040,6 +1038,10 @@ static void ceph_kill_sb(struct super_block *s)
ceph_mdsc_pre_umount(fsc->mdsc);
generic_shutdown_super(s);
+
+ fsc->client->extra_mon_dispatch = NULL;
+ ceph_fs_debugfs_cleanup(fsc);
+
ceph_mdsc_destroy(fsc);
destroy_fs_client(fsc);