]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: cleanup in check_new_map() method
authorViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Thu, 11 Sep 2025 18:16:10 +0000 (11:16 -0700)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 11 Feb 2026 18:19:17 +0000 (19:19 +0100)
The Coverity Scan service has reported a potential issue
in check_new_map() method [1]. The check_new_map() executes
checking of newmap->m_info on NULL in the beginning of
the method. However, it operates by newmap->m_info later
in the method without any check on NULL. Analysis of the code
flow shows that ceph_mdsmap_decode() guarantees the allocation
of m_info array. And check_new_map() never will be called
with newmap->m_info not allocated.

This patch exchanges checking of newmap->m_info on BUG_ON()
pattern because the situation of having NULL in newmap->m_info
during check_new_map() is not expecting event. Also, this patch
reworks logic of __open_export_target_sessions(),
ceph_mdsmap_get_addr(), ceph_mdsmap_get_state(), and
ceph_mdsmap_is_laggy() by checking mdsmap->m_info on NULL value.

[1] https://scan5.scan.coverity.com/#/project-view/64304/10063?selectedIssue=1491799

Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
cc: Alex Markuze <amarkuze@redhat.com>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Ceph Development <ceph-devel@vger.kernel.org>

fs/ceph/debugfs.c
fs/ceph/mds_client.c
fs/ceph/mdsmap.h

index f3fe786b4143d4bd7a24ed33351c8c9059a8112d..6a7f418aa9e5cd4931a08d7e8995530b25619768 100644 (file)
@@ -37,8 +37,15 @@ static int mdsmap_show(struct seq_file *s, void *p)
        seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout);
        seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose);
        for (i = 0; i < mdsmap->possible_max_rank; i++) {
-               struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
-               int state = mdsmap->m_info[i].state;
+               struct ceph_entity_addr *addr;
+               int state;
+
+               if (unlikely(!mdsmap->m_info))
+                       break;
+
+               addr = &mdsmap->m_info[i].addr;
+               state = mdsmap->m_info[i].state;
+
                seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
                               ceph_pr_addr(addr),
                               ceph_mds_state_name(state));
index 770ff0a0f7ad1155e8fd0097c0440fbe27f58095..6a9f5b4f508807f4482f3cf921812fc334c1f38c 100644 (file)
@@ -1739,6 +1739,9 @@ static void __open_export_target_sessions(struct ceph_mds_client *mdsc,
        if (mds >= mdsc->mdsmap->possible_max_rank)
                return;
 
+       if (unlikely(!mdsc->mdsmap->m_info))
+               return;
+
        mi = &mdsc->mdsmap->m_info[mds];
        doutc(cl, "for mds%d (%d targets)\n", session->s_mds,
              mi->num_export_targets);
@@ -5109,11 +5112,12 @@ static void check_new_map(struct ceph_mds_client *mdsc,
 
        doutc(cl, "new %u old %u\n", newmap->m_epoch, oldmap->m_epoch);
 
-       if (newmap->m_info) {
-               for (i = 0; i < newmap->possible_max_rank; i++) {
-                       for (j = 0; j < newmap->m_info[i].num_export_targets; j++)
-                               set_bit(newmap->m_info[i].export_targets[j], targets);
-               }
+       /* ceph_mdsmap_decode() should guarantee m_info allocation */
+       BUG_ON(!newmap->m_info);
+
+       for (i = 0; i < newmap->possible_max_rank; i++) {
+               for (j = 0; j < newmap->m_info[i].num_export_targets; j++)
+                       set_bit(newmap->m_info[i].export_targets[j], targets);
        }
 
        for (i = 0; i < oldmap->possible_max_rank && i < mdsc->max_sessions; i++) {
index d48d07c3516d447a8f3e684f6ded1f1ca1674417..c3d8c0ad6aba6d77f9811f2dbed5730361641964 100644 (file)
@@ -53,6 +53,8 @@ ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
 {
        if (w >= m->possible_max_rank)
                return NULL;
+       if (unlikely(!m->m_info))
+               return NULL;
        return &m->m_info[w].addr;
 }
 
@@ -61,12 +63,14 @@ static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
        BUG_ON(w < 0);
        if (w >= m->possible_max_rank)
                return CEPH_MDS_STATE_DNE;
+       if (unlikely(!m->m_info))
+               return CEPH_MDS_STATE_DNE;
        return m->m_info[w].state;
 }
 
 static inline bool ceph_mdsmap_is_laggy(struct ceph_mdsmap *m, int w)
 {
-       if (w >= 0 && w < m->possible_max_rank)
+       if (w >= 0 && w < m->possible_max_rank && m->m_info)
                return m->m_info[w].laggy;
        return false;
 }