GHSA-M843-78WR-M386
Vulnerability from github – Published: 2026-09-11 21:31 – Updated: 2026-09-13 09:32In the Linux kernel, the following vulnerability has been resolved:
ceph: do not repeat ceph_trim_dentries() if no progress possible
ceph_cap_reclaim_work() re-queues itself for as long as
ceph_trim_dentries() returns -EAGAIN, which happens whenever a lease
walk exhausts its nr_to_scan budget. This creates a busy loop that
consumes CPU without making any progress when there is nothing to
reclaim: with no cap pressure (count==0) and every scanned lease
still valid, each pass runs the full scan budget down to zero and
returns -EAGAIN, only to be queued again immediately.
The dir-lease walk made this worse. When expire_dir_lease is
false (i.e. we have no intention of reclaiming dir leases),
__dir_lease_check() returned TOUCH for every valid lease. TOUCH
moves the dentry to the tail of the list and resets di->time via
__dentry_dir_lease_touch(), so a walk over N valid leases pointlessly
rewrote the list, refreshed the timestamps (preventing them from ever
aging out) and always drained nr_to_scan, guaranteeing the -EAGAIN
requeue.
Fix this in three steps:
-
Return
KEEPinstead ofTOUCHwhenexpire_dir_leaseisfalse. If we are not going to reclaim the lease, leave it in place instead of churning the list and resetting its timestamp; the walk then terminates naturally (or viaSTOPat the first fresh lease). -
Only return
-EAGAINfrom the first (dentry-lease) walk when something was actually freed. A full batch that frees nothing means retrying the same list immediately is futile; fall through to the dir-lease walk instead. -
After both walks, bail out with success (0) when nothing was freed and there is no cap pressure (
count==0). There is no reason to keep retrying when we are not over the cap limit and made no progress.
Under real cap pressure (count>0) the reclaim path is unchanged and
still retries via -EAGAIN.
Without this patch, I saw 500 ceph_trim_dentries() calls per second on
our web servers. This is very visible in /proc/lock_stat (5 minute
capture):
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 126180 128218 0.04 8063.44 15986965.20 124.69 1573354 5296812 0.04 8291.28 74164526.48 14.00
&mdsc->dentry_list_lock 111736 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 2631 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8 &mdsc->dentry_list_lock 3878 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8 &mdsc->dentry_list_lock 9973 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0
&mdsc->dentry_list_lock 123621 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8 &mdsc->dentry_list_lock 1822 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 2720 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0 &mdsc->dentry_list_lock 55 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8
With this patch:
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 1203 1215 0.16 408.88 33082.88 27.23 4320501 7357389 0.04 500.64 1961578.00 0.27
&mdsc->dentry_list_lock 1029 [<000000003c9aea8a>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 1 ---truncated---
{
"affected": [],
"aliases": [
"CVE-2026-89647"
],
"database_specific": {
"cwe_ids": [],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-11T20:19:50Z",
"severity": "HIGH"
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nceph: do not repeat ceph_trim_dentries() if no progress possible\n\nceph_cap_reclaim_work() re-queues itself for as long as\nceph_trim_dentries() returns -EAGAIN, which happens whenever a lease\nwalk exhausts its `nr_to_scan` budget. This creates a busy loop that\nconsumes CPU without making any progress when there is nothing to\nreclaim: with no cap pressure (`count==0`) and every scanned lease\nstill valid, each pass runs the full scan budget down to zero and\nreturns `-EAGAIN`, only to be queued again immediately.\n\nThe dir-lease walk made this worse. When `expire_dir_lease` is\n`false` (i.e. we have no intention of reclaiming dir leases),\n__dir_lease_check() returned `TOUCH` for every valid lease. `TOUCH`\nmoves the dentry to the tail of the list and resets `di-\u003etime` via\n__dentry_dir_lease_touch(), so a walk over N valid leases pointlessly\nrewrote the list, refreshed the timestamps (preventing them from ever\naging out) and always drained `nr_to_scan`, guaranteeing the `-EAGAIN`\nrequeue.\n\nFix this in three steps:\n\n - Return `KEEP` instead of `TOUCH` when `expire_dir_lease` is\n `false`. If we are not going to reclaim the lease, leave it in\n place instead of churning the list and resetting its timestamp; the\n walk then terminates naturally (or via `STOP` at the first fresh\n lease).\n\n - Only return `-EAGAIN` from the first (dentry-lease) walk when something\n was actually freed. A full batch that frees nothing means retrying\n the same list immediately is futile; fall through to the dir-lease\n walk instead.\n\n - After both walks, bail out with success (0) when nothing was freed\n and there is no cap pressure (`count==0`). There is no reason to\n keep retrying when we are not over the cap limit and made no\n progress.\n\nUnder real cap pressure (`count\u003e0`) the reclaim path is unchanged and\nstill retries via `-EAGAIN`.\n\nWithout this patch, I saw 500 ceph_trim_dentries() calls per second on\nour web servers. This is very visible in `/proc/lock_stat` (5 minute\ncapture):\n\n class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg\n\n \u0026mdsc-\u003edentry_list_lock: 126180 128218 0.04 8063.44 15986965.20 124.69 1573354 5296812 0.04 8291.28 74164526.48 14.00\n -----------------------\n \u0026mdsc-\u003edentry_list_lock 111736 [\u003c000000007b11e319\u003e] __ceph_dentry_dir_lease_touch+0x7c/0xa8\n \u0026mdsc-\u003edentry_list_lock 2631 [\u003c0000000050597999\u003e] __dentry_leases_walk+0x64/0x2c8\n \u0026mdsc-\u003edentry_list_lock 3878 [\u003c00000000c0022f62\u003e] __ceph_dentry_lease_touch+0x5c/0xa8\n \u0026mdsc-\u003edentry_list_lock 9973 [\u003c000000002f27cb6f\u003e] __dentry_lease_unlist+0x50/0xa0\n -----------------------\n \u0026mdsc-\u003edentry_list_lock 123621 [\u003c0000000050597999\u003e] __dentry_leases_walk+0x64/0x2c8\n \u0026mdsc-\u003edentry_list_lock 1822 [\u003c000000007b11e319\u003e] __ceph_dentry_dir_lease_touch+0x7c/0xa8\n \u0026mdsc-\u003edentry_list_lock 2720 [\u003c000000002f27cb6f\u003e] __dentry_lease_unlist+0x50/0xa0\n \u0026mdsc-\u003edentry_list_lock 55 [\u003c00000000c0022f62\u003e] __ceph_dentry_lease_touch+0x5c/0xa8\n\nWith this patch:\n\n class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg\n\n \u0026mdsc-\u003edentry_list_lock: 1203 1215 0.16 408.88 33082.88 27.23 4320501 7357389 0.04 500.64 1961578.00 0.27\n -----------------------\n \u0026mdsc-\u003edentry_list_lock 1029 [\u003c000000003c9aea8a\u003e] __ceph_dentry_dir_lease_touch+0x7c/0xa8\n \u0026mdsc-\u003edentry_list_lock 1\n---truncated---",
"id": "GHSA-m843-78wr-m386",
"modified": "2026-09-13T09:32:26Z",
"published": "2026-09-11T21:31:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-89647"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/37d6edb2f03b29399a3a337fae78674de51e1695"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/3d122b2feb1dd76bb5041bdea5e1e1b007d8d415"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/5a541eb401acb89d791da41189d7a79220164b93"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/e7d7aa7b730178278109c41fa1b17b06873065d5"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.