From 9c37b12b29753bcfa07da576d8e4e8f60d758f5d Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 14 Feb 2020 10:45:47 +0800 Subject: [PATCH] mds: fix use-after-free in Migrater use PIN_PTRWAITER to pin CDir in MigratorContext. Also pin CDir to MDRequest because export may get cancelled while acquiring locks. Fixes: https://tracker.ceph.com/issues/43909 Signed-off-by: "Yan, Zheng" (cherry picked from commit 6203c27b1e48438450524b7c40bb036e5897f207) --- src/mds/Migrator.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 8823aee8cde..98bf78c3b73 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -156,9 +156,13 @@ void Migrator::dispatch(const Message::const_ref &m) class C_MDC_EmptyImport : public MigratorContext { CDir *dir; public: - C_MDC_EmptyImport(Migrator *m, CDir *d) : MigratorContext(m), dir(d) {} + C_MDC_EmptyImport(Migrator *m, CDir *d) : + MigratorContext(m), dir(d) { + dir->get(CDir::PIN_PTRWAITER); + } void finish(int r) override { mig->export_empty_import(dir); + dir->put(CDir::PIN_PTRWAITER); } }; @@ -719,16 +723,17 @@ void Migrator::maybe_do_queued_export() class C_MDC_ExportFreeze : public MigratorContext { - CDir *ex; // dir i'm exporting + CDir *dir; // dir i'm exporting uint64_t tid; public: C_MDC_ExportFreeze(Migrator *m, CDir *e, uint64_t t) : - MigratorContext(m), ex(e), tid(t) { - ceph_assert(ex != NULL); - } + MigratorContext(m), dir(e), tid(t) { + dir->get(CDir::PIN_PTRWAITER); + } void finish(int r) override { if (r >= 0) - mig->export_frozen(ex, tid); + mig->export_frozen(dir, tid); + dir->put(CDir::PIN_PTRWAITER); } }; @@ -855,6 +860,7 @@ void Migrator::export_dir(CDir *dir, mds_rank_t dest) MDRequestRef mdr = mds->mdcache->request_start_internal(CEPH_MDS_OP_EXPORTDIR); mdr->more()->export_dir = dir; + mdr->pin(dir); ceph_assert(export_state.count(dir) == 0); export_state_t& stat = export_state[dir]; @@ -1139,6 +1145,7 @@ void Migrator::dispatch_export_dir(MDRequestRef& mdr, int count) MDRequestRef _mdr = mds->mdcache->request_start_internal(CEPH_MDS_OP_EXPORTDIR); _mdr->more()->export_dir = sub; + _mdr->pin(sub); ceph_assert(export_state.count(sub) == 0); auto& stat = export_state[sub]; @@ -1216,12 +1223,13 @@ class C_M_ExportSessionsFlushed : public MigratorContext { CDir *dir; uint64_t tid; public: - C_M_ExportSessionsFlushed(Migrator *m, CDir *d, uint64_t t) - : MigratorContext(m), dir(d), tid(t) { - ceph_assert(dir != NULL); + C_M_ExportSessionsFlushed(Migrator *m, CDir *d, uint64_t t) : + MigratorContext(m), dir(d), tid(t) { + dir->get(CDir::PIN_PTRWAITER); } void finish(int r) override { mig->export_sessions_flushed(dir, tid); + dir->put(CDir::PIN_PTRWAITER); } }; @@ -1502,10 +1510,11 @@ class C_M_ExportGo : public MigratorContext { public: C_M_ExportGo(Migrator *m, CDir *d, uint64_t t) : MigratorContext(m), dir(d), tid(t) { - ceph_assert(dir != NULL); - } + dir->get(CDir::PIN_PTRWAITER); + } void finish(int r) override { mig->export_go_synced(dir, tid); + dir->put(CDir::PIN_PTRWAITER); } }; @@ -2595,9 +2604,11 @@ public: C_MDS_ImportDirLoggedStart(Migrator *m, CDir *d, mds_rank_t f) : MigratorLogContext(m), df(d->dirfrag()), dir(d), from(f) { + dir->get(CDir::PIN_PTRWAITER); } void finish(int r) override { mig->import_logged_start(df, dir, from, imported_session_map); + dir->put(CDir::PIN_PTRWAITER); } }; @@ -2957,6 +2968,8 @@ void Migrator::import_reverse_final(CDir *dir) void Migrator::import_logged_start(dirfrag_t df, CDir *dir, mds_rank_t from, map >& imported_session_map) { + dout(7) << "import_logged " << *dir << dendl; + map::iterator it = import_state.find(dir->dirfrag()); if (it == import_state.end() || it->second.state != IMPORT_LOGGINGSTART) { @@ -2965,8 +2978,6 @@ void Migrator::import_logged_start(dirfrag_t df, CDir *dir, mds_rank_t from, return; } - dout(7) << "import_logged " << *dir << dendl; - // note state it->second.state = IMPORT_ACKING; -- 2.47.3