{"id":40979,"date":"2026-10-19T00:31:43","date_gmt":"2026-10-18T16:31:43","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98507"},"modified":"2026-10-19T00:31:43","modified_gmt":"2026-10-18T16:31:43","slug":"cve-2026-98507","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98507","title":{"rendered":"CVE-2026-98507 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nmm\/rmap: fix missing"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>mm\/rmap: fix missing barrier between anon_vma init and vma-&gt;anon_vma publish<\/p>\n<p>On arm64 server, we find that a task trying to grab the anon_vma lock<br \/>\ntriggers hungtask.<\/p>\n<p>INFO: task main:2354726 blocked for more than 120 seconds.<br \/>\n      Tainted: G            E     5.10.0-0021.aarch64 #1<br \/>\n&#8220;echo 0 &gt; \/proc\/sys\/kernel\/hung_task_timeout_secs&#8221; disables this message.<br \/>\ntask:main            state:D stack:    0 pid:2354726 ppid:2350673 flags:0x00000a01<br \/>\nCall trace:<br \/>\n __switch_to+0x7c\/0xbc<br \/>\n __schedule+0x3b4\/0x8a0<br \/>\n schedule+0x50\/0xe0<br \/>\n rwsem_down_write_slowpath+0x3cc\/0x6cc<br \/>\n down_write+0x60\/0x260<br \/>\n __anon_vma_prepare+0x6c\/0x210<br \/>\n do_anonymous_page+0x258\/0x660<br \/>\n handle_pte_fault+0x188\/0x214<br \/>\n __handle_mm_fault+0x1b0\/0x380<br \/>\n handle_mm_fault+0xf4\/0x284<br \/>\n do_page_fault+0x19c\/0x494<br \/>\n do_translation_fault+0xcc\/0xf8<br \/>\n do_mem_abort+0x48\/0xac<br \/>\n el0_da+0x44\/0x80<br \/>\n el0_sync_handler+0x88\/0xb4<br \/>\n el0_sync+0x160\/0x180<\/p>\n<p>After analyzing the vmcore, we found the anon_vma-&gt;root-&gt;rwsem.count is<br \/>\n-1.  There is another anon_vma whose anon_vma-&gt;root-&gt;rwsem.count is 1, the<br \/>\nanon_vma-&gt;root-&gt;rwsem.owner shows the lock is held, but the stack of the<br \/>\ntask shows the task doesn&#8217;t hold the anon_vma lock.<\/p>\n<p>After adding more debugging info, we found __anon_vma_prepare() reuses<br \/>\nanon_vma and triggers the UAF of anon_vma-&gt;root due to missing memory<br \/>\nbarrier, leading to locking and unlocking two different anon_vma-&gt;root,<br \/>\nthus leading to an anon_vma will never be unlocked, and another anon_vma<br \/>\ncouldn&#8217;t be locked anymore.<\/p>\n<p>This race requires two adjacent VMAs that are not merged but are<br \/>\nanon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be<br \/>\nchanged by mprotect()).  Two threads fault on each VMA concurrently, both<br \/>\ncalling __anon_vma_prepare() with only mmap_lock held for reading.<\/p>\n<p>    THREAD A                             THREAD B<br \/>\n__anon_vma_prepare                __anon_vma_prepare<br \/>\n find_mergeable_anon_vma() -&gt; NULL<br \/>\n anon_vma = anon_vma_alloc();<br \/>\n   anon_vma-&gt;root = anon_vma;<br \/>\n \/\/ the two stores may be reordered<br \/>\n vma-&gt;anon_vma = anon_vma;<br \/>\n                                   \/\/ finds A&#8217;s anon_vma<br \/>\n                                   anon_vma = find_mergeable_anon_vma(vma);<br \/>\n                                   anon_vma_lock_write(anon_vma);<br \/>\n                                     \/\/ may still see the old root<br \/>\n                                     down_write(&amp;anon_vma-&gt;root-&gt;rwsem);<br \/>\n                                   anon_vma_unlock_write(anon_vma);<br \/>\n                                     \/\/ see the new root, never unlock old<br \/>\n                                     up_write(&amp;anon_vma-&gt;root-&gt;rwsem);<\/p>\n<p>thread A triggers page fault and calls __anon_vma_prepare() to prepare<br \/>\nanon_vma for the faulting vma.  __anon_vma_prepare() allocates and<br \/>\ninitializes a new anon_vma, and then publishes it to the vma with a plain<br \/>\nstore.  anon_vma_prepare() only requires the mmap_lock to be held for<br \/>\nreading, so two threads can fault on adjacent VMAs at the same time.<br \/>\nWhile thread A publishes a new anon_vma, thread B could find the anon_vma<br \/>\nvia find_mergeable_anon_vma() and then locks anon_vma-&gt;root-&gt;rwsem.<\/p>\n<p>The store to anon_vma-&gt;root in anon_vma_alloc() and the store to<br \/>\nvma-&gt;anon_vma can be reordered.  The anon_vma_lock_write() and spin_lock()<br \/>\nonly provide acquire semantics, which do not prevent prior stores from<br \/>\nbeing reordered after them.  The release semantics of the corresponding<br \/>\nspin_unlock() and anon_vma_unlock_write() come too late, the store to<br \/>\nvma-&gt;anon_vma is already published before they take effect.  As a result,<br \/>\nthread B can observe the following order:<\/p>\n<p>    vma-&gt;anon_vma = anon_vma;<br \/>\n    anon_vma-&gt;root = anon_vma;<\/p>\n<p>The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma<br \/>\nmay reuse memory from a previously freed one.  The constructor<br \/>\n(anon_vma_ctor) does not reset anon_vma-&gt;root, and __put_anon_vma()<br \/>\ndoesn&#8217;t clear it either, so the old root value persists until<br \/>\nanon_vma_alloc() overwrites it.  If that store isn&#8217;t v<br \/>\n&#8212;truncated&#8212;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>mm\/rmap: fix missing barrier between anon_vma init and vma-&gt;anon_vma publish<\/p>\n<p>On arm64 server, we find that a task trying to grab t<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-40979","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/40979","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=40979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=40979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=40979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}