]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: add auth_lock to protect auth_meta manipulation
authorSage Weil <sage@redhat.com>
Thu, 31 Jan 2019 19:10:31 +0000 (13:10 -0600)
committerSage Weil <sage@redhat.com>
Thu, 7 Feb 2019 18:10:34 +0000 (12:10 -0600)
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 <sage@redhat.com>
src/mon/Monitor.cc
src/mon/Monitor.h

index 83e0205b87d85833223f5c8b84dd12b9d55d6ffc..c9e433059900aca7b7219646b0b72cb2b540247e 100644 (file)
@@ -5873,17 +5873,19 @@ int Monitor::get_auth_request(
   vector<uint32_t> *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.
 
index b4c773390c046ccd6e7d78e0d517593e1ca42db0..6c528ab522f51da54ba478b061c349de5a206edf 100644 (file)
@@ -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.