From 574e6bf6ad4aca621b7651889fe852d4f6074dc1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 Jan 2019 13:10:31 -0600 Subject: [PATCH] mon: add auth_lock to protect auth_meta manipulation In particular, we could be handling a get_auth_request() on a reconnect while also running handle_auth_request() on a racing connection between monitors. Signed-off-by: Sage Weil --- src/mon/Monitor.cc | 16 +++++++++++----- src/mon/Monitor.h | 4 +++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 83e0205b87d..c9e43305990 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -5873,17 +5873,19 @@ int Monitor::get_auth_request( vector *preferred_modes, bufferlist *out) { - AuthAuthorizer *auth; - if (!ms_get_authorizer(con->get_peer_type(), &auth)) { + std::scoped_lock l(auth_lock); + if (con->get_peer_type() != CEPH_ENTITY_TYPE_MON) { return -EACCES; } - if (con->get_peer_type() != CEPH_ENTITY_TYPE_MON) { + AuthAuthorizer *auth; + if (!ms_get_authorizer(con->get_peer_type(), &auth)) { return -EACCES; } auth_meta->authorizer.reset(auth); - *method = auth->protocol; - auth_registry.get_supported_modes(CEPH_ENTITY_TYPE_MON, auth->protocol, + auth_registry.get_supported_modes(CEPH_ENTITY_TYPE_MON, + auth->protocol, preferred_modes); + *method = auth->protocol; *out = auth->bl; return 0; } @@ -5894,6 +5896,7 @@ int Monitor::handle_auth_reply_more( const bufferlist& bl, bufferlist *reply) { + std::scoped_lock l(auth_lock); if (!auth_meta->authorizer) { derr << __func__ << " no authorizer?" << dendl; return -EACCES; @@ -5912,6 +5915,7 @@ int Monitor::handle_auth_done( CryptoKey *session_key, std::string *connection_secret) { + std::scoped_lock l(auth_lock); // verify authorizer reply auto p = bl.begin(); if (!auth_meta->authorizer->verify_reply(p, connection_secret)) { @@ -6036,6 +6040,8 @@ int Monitor::handle_auth_request( const bufferlist &payload, bufferlist *reply) { + std::scoped_lock l(auth_lock); + // NOTE: be careful, the Connection hasn't fully negotiated yet, so // e.g., peer_features, peer_addrs, and others are still unknown. diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index b4c773390c0..6c528ab522f 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -141,7 +141,9 @@ public: SafeTimer timer; Finisher finisher; ThreadPool cpu_tp; ///< threadpool for CPU intensive work - + + ceph::mutex auth_lock = ceph::make_mutex("Monitor::auth_lock"); + /// true if we have ever joined a quorum. if false, we are either a /// new cluster, a newly joining monitor, or a just-upgraded /// monitor. -- 2.39.5