{"id":11940,"date":"2026-09-04T18:53:58","date_gmt":"2026-09-04T10:53:58","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-80527"},"modified":"2026-09-04T18:53:58","modified_gmt":"2026-09-04T10:53:58","slug":"cve-2026-80527","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-80527","title":{"rendered":"CVE-2026-80527 [HIGH] &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nceph: fix hanging __c"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>ceph: fix hanging __ceph_get_caps() with stale mds_wanted<\/p>\n<p>A reader can hang forever in __ceph_get_caps() when the client no<br \/>\nlonger holds `FILE_RD`, but local cap state still says that the<br \/>\ncapability is already wanted (via `mds_wanted`).<\/p>\n<p>One way to trigger this is through MDS cap revocation.  If another<br \/>\nclient performs a conflicting operation, the MDS can revoke `FILE_RD`<br \/>\nfrom the reader; the next read then has to reacquire `FILE_RD`.  If<br \/>\nthe cap update that should request `FILE_RD` never reaches the MDS<br \/>\nafter `cap-&gt;mds_wanted` was raised, the reader is left holding only<br \/>\nnon-file caps while local `mds_wanted` still includes the file read<br \/>\ncaps.<\/p>\n<p>In that state, try_get_cap_refs() sees `need mds_wanted was` raised, no further request is sent and the<br \/>\nwaiter can sleep indefinitely until unrelated cap traffic happens to<br \/>\nwake it up.<\/p>\n<p>The ordering issue is that `cap-&gt;mds_wanted` is updated in<br \/>\n__prep_cap() before the `CEPH_MSG_CLIENT_CAPS message` is actually<br \/>\nqueued for send.  That makes one field serve two different meanings at<br \/>\nonce: what this client wants, and what the client believes the MDS<br \/>\nalready knows it wants.<\/p>\n<p>A proper fix would be to split those states and track whether a cap<br \/>\nupdate is actually in flight or has been observed by the MDS.<br \/>\nHowever, simply moving the `cap-&gt;mds_wanted assignment` later would<br \/>\nnot be sufficient: queueing the message in the messenger does not<br \/>\nguarantee that the MDS processed that specific wanted set, and<br \/>\nreconnect or message loss can still invalidate that assumption.<br \/>\nFixing that properly would require a larger rework of the cap state<br \/>\nmachine.<\/p>\n<p>To allow simpler backports to stable kernels, this patch implements a<br \/>\nsimpler workaround:<\/p>\n<p>&#8211; stop waiting forever in __ceph_get_caps(); after a bounded wait,<br \/>\n  fall back to the renew path<\/p>\n<p>&#8211; make ceph_renew_caps() issue a synchronous `OPEN` request whenever<br \/>\n  the inode still does not actually hold the wanted caps, instead of<br \/>\n  only calling ceph_check_caps()<\/p>\n<p>The extra issued-vs-wanted check in ceph_renew_caps() is necessary<br \/>\nbecause the previous test only checked whether the inode still had any<br \/>\nreal caps at all.  That is not enough after revocation: the client can<br \/>\nstill hold something like `pLs` and yet be missing `FILE_RD`<br \/>\ncompletely.  In that case, falling back to ceph_check_caps() is not<br \/>\nsufficient, because it still trusts `cap-&gt;mds_wanted` and may resend<br \/>\nnothing.  By requiring `(issued &amp; wanted) == wanted` before taking the<br \/>\nasynchronous path, the code only uses ceph_check_caps() when the<br \/>\n`wanted caps` are already actually issued.  Otherwise, it sends the<br \/>\nsynchronous `OPEN` renew.<\/p>\n<p>This preserves the existing asynchronous fast path when the wanted<br \/>\ncaps are already issued, avoids changing cap-state semantics, and<br \/>\nfixes the hang by guaranteeing that a stalled waiter eventually<br \/>\nretries through a path that does not rely on the stale `mds_wanted`<br \/>\nstate.<\/p>\n<p>[ idryomov: move CEPH_GET_CAPS_WAIT_TIMEOUT from libceph.h to<br \/>\n  mds_client.h, formatting ]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>ceph: fix hanging __ceph_get_caps() with stale mds_wanted<\/p>\n<p>A reader can hang forever in __ceph_get_caps() when the client no<br \/>\nlonger<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-11940","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/11940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11940"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11940"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}