{"api_version":"1","generated_at":"2026-09-13T04:36:19+00:00","cve":"CVE-2026-89654","urls":{"html":"https://cve.report/CVE-2026-89654","api":"https://cve.report/api/cve/CVE-2026-89654.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-89654","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-89654"},"summary":{"title":"ceph: fix UAF in check_new_map() on session freed during unlock","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nceph: fix UAF in check_new_map() on session freed during unlock\n\ncheck_new_map() iterates mdsc->sessions[] and for each active session\ndrops mdsc->mutex to perform per-session operations.  The forced-close\npath (rank removed from map) correctly takes a reference on s via\nceph_get_mds_session() before releasing mdsc->mutex, but three other\npaths do not:\n\n  Path A (address changed):  mutex_unlock → mutex_lock(&s->s_mutex)\n  Path B (reconnect):        mutex_unlock → send_mds_reconnect(mdsc, s)\n  Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex)\n\nWithout the extra reference, another thread can acquire mdsc->mutex\nduring the unlock window, call __unregister_session() which drops the\nlast reference on s, and free it.  The original thread then accesses\nfreed memory via s->s_mutex.\n\nFix by adding ceph_get_mds_session(s) before each mutex_unlock and\nceph_put_mds_session(s) after the corresponding mutex_lock, matching\nthe pattern already used in the forced-close path.\n\nRace timeline (Path A):\n\n  Thread A (check_new_map)             Thread B (another map update\n    holds mdsc->mutex                      or session teardown)\n  --------------------------           --------------------------\n  s = mdsc->sessions[i]\n  (refcount == 1, held only by\n   sessions[] array)\n\n  mutex_unlock(&mdsc->mutex)\n                               --->    acquires mdsc->mutex\n                                       __unregister_session(mdsc, s)\n                                         sessions[i] = NULL\n                                         ceph_put_mds_session(s)\n                                           refcount: 1 -> 0\n                                           kfree(s)  <--- freed!\n\n  mutex_lock(&s->s_mutex)\n  UAF on freed s->s_mutex","state":"PUBLISHED","assigner":"Linux","published_at":"2026-09-11 20:19:51","updated_at":"2026-09-11 20:19:51"},"problem_types":[],"metrics":[],"references":[{"url":"https://git.kernel.org/stable/c/21d5be092d947f8d83f76f7ebf3989e7e9230a98","name":"https://git.kernel.org/stable/c/21d5be092d947f8d83f76f7ebf3989e7e9230a98","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/ee611a7509554c4ca1f54f6aefe592fb1df7ea70","name":"https://git.kernel.org/stable/c/ee611a7509554c4ca1f54f6aefe592fb1df7ea70","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-89654","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-89654","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 21d5be092d947f8d83f76f7ebf3989e7e9230a98 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ee611a7509554c4ca1f54f6aefe592fb1df7ea70 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 7.2.4 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.2.4 7.2.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.3-rc1 * original_commit_for_fix","platforms":[]}],"timeline":[],"solutions":[],"workarounds":[],"exploits":[],"credits":[],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":{"cve_year":"2026","cve_id":"89654","cve":"CVE-2026-89654","epss":"0.001620000","percentile":"0.057510000","score_date":"2026-09-12","updated_at":"2026-09-13 00:08:17"},"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"defaultStatus":"unaffected","product":"Linux","programFiles":["fs/ceph/mds_client.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThan":"21d5be092d947f8d83f76f7ebf3989e7e9230a98","status":"affected","version":"1da177e4c3f41524e886b7f1b8a0c1fc7321cac2","versionType":"git"},{"lessThan":"ee611a7509554c4ca1f54f6aefe592fb1df7ea70","status":"affected","version":"1da177e4c3f41524e886b7f1b8a0c1fc7321cac2","versionType":"git"},{"lessThan":"7.2.4","status":"affected","version":"0","versionType":"semver"}]},{"defaultStatus":"affected","product":"Linux","programFiles":["fs/ceph/mds_client.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThanOrEqual":"7.2.*","status":"unaffected","version":"7.2.4","versionType":"semver"},{"lessThanOrEqual":"*","status":"unaffected","version":"7.3-rc1","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.2.4","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.3-rc1","vulnerable":true}],"negate":false,"operator":"OR"}]}],"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nceph: fix UAF in check_new_map() on session freed during unlock\n\ncheck_new_map() iterates mdsc->sessions[] and for each active session\ndrops mdsc->mutex to perform per-session operations.  The forced-close\npath (rank removed from map) correctly takes a reference on s via\nceph_get_mds_session() before releasing mdsc->mutex, but three other\npaths do not:\n\n  Path A (address changed):  mutex_unlock → mutex_lock(&s->s_mutex)\n  Path B (reconnect):        mutex_unlock → send_mds_reconnect(mdsc, s)\n  Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex)\n\nWithout the extra reference, another thread can acquire mdsc->mutex\nduring the unlock window, call __unregister_session() which drops the\nlast reference on s, and free it.  The original thread then accesses\nfreed memory via s->s_mutex.\n\nFix by adding ceph_get_mds_session(s) before each mutex_unlock and\nceph_put_mds_session(s) after the corresponding mutex_lock, matching\nthe pattern already used in the forced-close path.\n\nRace timeline (Path A):\n\n  Thread A (check_new_map)             Thread B (another map update\n    holds mdsc->mutex                      or session teardown)\n  --------------------------           --------------------------\n  s = mdsc->sessions[i]\n  (refcount == 1, held only by\n   sessions[] array)\n\n  mutex_unlock(&mdsc->mutex)\n                               --->    acquires mdsc->mutex\n                                       __unregister_session(mdsc, s)\n                                         sessions[i] = NULL\n                                         ceph_put_mds_session(s)\n                                           refcount: 1 -> 0\n                                           kfree(s)  <--- freed!\n\n  mutex_lock(&s->s_mutex)\n  UAF on freed s->s_mutex"}],"providerMetadata":{"dateUpdated":"2026-09-11T19:45:44.086Z","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux"},"references":[{"url":"https://git.kernel.org/stable/c/21d5be092d947f8d83f76f7ebf3989e7e9230a98"},{"url":"https://git.kernel.org/stable/c/ee611a7509554c4ca1f54f6aefe592fb1df7ea70"}],"title":"ceph: fix UAF in check_new_map() on session freed during unlock","x_generator":{"engine":"bippy-1.2.0"}}},"cveMetadata":{"assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","assignerShortName":"Linux","cveId":"CVE-2026-89654","datePublished":"2026-09-11T19:45:44.086Z","dateReserved":"2026-09-11T19:38:34.743Z","dateUpdated":"2026-09-11T19:45:44.086Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-09-11 20:19:51","lastModifiedDate":"2026-09-11 20:19:51","problem_types":[],"metrics":[],"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"89654","Ordinal":"1","Title":"ceph: fix UAF in check_new_map() on session freed during unlock","CVE":"CVE-2026-89654","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"89654","Ordinal":"1","NoteData":"In the Linux kernel, the following vulnerability has been resolved:\n\nceph: fix UAF in check_new_map() on session freed during unlock\n\ncheck_new_map() iterates mdsc->sessions[] and for each active session\ndrops mdsc->mutex to perform per-session operations.  The forced-close\npath (rank removed from map) correctly takes a reference on s via\nceph_get_mds_session() before releasing mdsc->mutex, but three other\npaths do not:\n\n  Path A (address changed):  mutex_unlock → mutex_lock(&s->s_mutex)\n  Path B (reconnect):        mutex_unlock → send_mds_reconnect(mdsc, s)\n  Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex)\n\nWithout the extra reference, another thread can acquire mdsc->mutex\nduring the unlock window, call __unregister_session() which drops the\nlast reference on s, and free it.  The original thread then accesses\nfreed memory via s->s_mutex.\n\nFix by adding ceph_get_mds_session(s) before each mutex_unlock and\nceph_put_mds_session(s) after the corresponding mutex_lock, matching\nthe pattern already used in the forced-close path.\n\nRace timeline (Path A):\n\n  Thread A (check_new_map)             Thread B (another map update\n    holds mdsc->mutex                      or session teardown)\n  --------------------------           --------------------------\n  s = mdsc->sessions[i]\n  (refcount == 1, held only by\n   sessions[] array)\n\n  mutex_unlock(&mdsc->mutex)\n                               --->    acquires mdsc->mutex\n                                       __unregister_session(mdsc, s)\n                                         sessions[i] = NULL\n                                         ceph_put_mds_session(s)\n                                           refcount: 1 -> 0\n                                           kfree(s)  <--- freed!\n\n  mutex_lock(&s->s_mutex)\n  UAF on freed s->s_mutex","Type":"Description","Title":"ceph: fix UAF in check_new_map() on session freed during unlock"}]}}}