]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mon: enforce cap checks upfront for map subscriptions
authorPatrick Donnelly <pdonnell@ibm.com>
Thu, 28 May 2026 15:15:26 +0000 (11:15 -0400)
committerPatrick Donnelly <pdonnell@ibm.com>
Fri, 29 May 2026 19:36:58 +0000 (15:36 -0400)
Move cap validation for mdsmap, fsmap, osdmap, osd_pg_creates, and kv to
the beginning of handle_subscribe. This prevents clients with
insufficient privileges from initiating unauthorized map subscriptions.

Fixes: https://tracker.ceph.com/issues/76964
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
src/mon/Monitor.cc

index 80bca9ca4b9a390f8c73fc12ce857aa1a3a48eec..b531b985690907c3595c5f408f71df02174a957d 100644 (file)
@@ -5425,6 +5425,34 @@ void Monitor::handle_subscribe(MonOpRequestRef op)
        ++p) {
     if (p->first == "monmap" || p->first == "config") {
       // these require no caps
+    } else if (p->first.compare(0, 6, "mdsmap") == 0 || p->first.compare(0, 5, "fsmap") == 0) {
+      if (!s->is_capable("mds", MON_CAP_R)) {
+        dout(5) << __func__ << " " << op->get_req()->get_source_inst()
+                << " not enough caps for " << p->first << " -- dropping"
+                << dendl;
+        continue;
+      }
+    } else if (p->first == "osdmap") {
+      if (!s->is_capable("osd", MON_CAP_R)) {
+        dout(5) << __func__ << " " << op->get_req()->get_source_inst()
+                << " not enough caps for " << p->first << " -- dropping"
+                << dendl;
+        continue;
+      }
+    } else if (p->first == "osd_pg_creates") {
+      if (!s->is_capable("osd", MON_CAP_W)) {
+        dout(5) << __func__ << " " << op->get_req()->get_source_inst()
+                << " not enough caps for " << p->first << " -- dropping"
+                << dendl;
+        continue;
+      }
+    } else if (p->first.compare(0, 2, "kv") == 0) {
+      if (!s->is_capable("config-key", MON_CAP_R)) {
+        dout(5) << __func__ << " " << op->get_req()->get_source_inst()
+                << " not enough caps for " << p->first << " -- dropping"
+                << dendl;
+        continue;
+      }
     } else if (!s->is_capable("mon", MON_CAP_R)) {
       dout(5) << __func__ << " " << op->get_req()->get_source_inst()
              << " not enough caps for " << *(op->get_req()) << " -- dropping"
@@ -5458,23 +5486,17 @@ void Monitor::handle_subscribe(MonOpRequestRef op)
 
     if (p->first.compare(0, 6, "mdsmap") == 0 || p->first.compare(0, 5, "fsmap") == 0) {
       dout(10) << __func__ << ": MDS sub '" << p->first << "'" << dendl;
-      if ((int)s->is_capable("mds", MON_CAP_R)) {
-        Subscription *sub = s->sub_map[p->first];
-        ceph_assert(sub != nullptr);
-        mdsmon()->check_sub(sub);
-      }
+      Subscription *sub = s->sub_map[p->first];
+      ceph_assert(sub != nullptr);
+      mdsmon()->check_sub(sub);
     } else if (p->first == "osdmap") {
-      if ((int)s->is_capable("osd", MON_CAP_R)) {
-       if (s->osd_epoch > p->second.start) {
-         // client needs earlier osdmaps on purpose, so reset the sent epoch
-         s->osd_epoch = 0;
-       }
-        osdmon()->check_osdmap_sub(s->sub_map["osdmap"]);
+      if (s->osd_epoch > p->second.start) {
+        // client needs earlier osdmaps on purpose, so reset the sent epoch
+        s->osd_epoch = 0;
       }
+      osdmon()->check_osdmap_sub(s->sub_map["osdmap"]);
     } else if (p->first == "osd_pg_creates") {
-      if ((int)s->is_capable("osd", MON_CAP_W)) {
-       osdmon()->check_pg_creates_sub(s->sub_map["osd_pg_creates"]);
-      }
+      osdmon()->check_pg_creates_sub(s->sub_map["osd_pg_creates"]);
     } else if (p->first == "monmap") {
       monmon()->check_sub(s->sub_map[p->first]);
     } else if (logmon()->sub_name_to_id(p->first) >= 0) {