<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Tue, 29 Sep 2026 02:35:35 +0000</lastBuildDate>
    <item>
      <title>CVE-2026-31398 — mm/rmap: fix incorrect pte restoration for lazyfree folios</title>
      <link>https://vulnerability.circl.lu/vuln/cve-2026-31398</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; Linux&lt;/p&gt;
&lt;p&gt;In the Linux kernel, the following vulnerability has been resolved:&lt;/p&gt;
&lt;p&gt;mm/rmap: fix incorrect pte restoration for lazyfree folios&lt;/p&gt;
&lt;p&gt;We batch unmap anonymous lazyfree folios by folio_unmap_pte_batch.  If the
batch has a mix of writable and non-writable bits, we may end up setting
the entire batch writable.  Fix this by respecting writable bit during
batching.&lt;/p&gt;
&lt;p&gt;Although on a successful unmap of a lazyfree folio, the soft-dirty bit is
lost, preserve it on pte restoration by respecting the bit during
batching, to make the fix consistent w.r.t both writable bit and
soft-dirty bit.&lt;/p&gt;
&lt;p&gt;I was able to write the below reproducer and crash the kernel. 
Explanation of reproducer (set 64K mTHP to always):&lt;/p&gt;
&lt;p&gt;Fault in a 64K large folio.  Split the VMA at mid-point with
MADV_DONTFORK.  fork() - parent points to the folio with 8 writable ptes
and 8 non-writable ptes.  Merge the VMAs with MADV_DOFORK so that
folio_unmap_pte_batch() can determine all the 16 ptes as a batch.  Do
MADV_FREE on the range to mark the folio as lazyfree.  Write to the memory
to dirty the pte, eventually rmap will dirty the folio.  Then trigger
reclaim, we will hit the pte restoration path, and the kernel will crash
with the trace given below.&lt;/p&gt;
&lt;p&gt;The BUG happens at:&lt;/p&gt;
&lt;p&gt;BUG_ON(atomic_inc_return(&amp;amp;ptc-&amp;gt;anon_map_count) &amp;gt; 1 &amp;amp;&amp;amp; rw);&lt;/p&gt;
&lt;p&gt;The code path is asking for anonymous page to be mapped writable into the
pagetable.  The BUG_ON() firing implies that such a writable page has been
mapped into the pagetables of more than one process,…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; Linux&lt;/p&gt;
&lt;p&gt;In the Linux kernel, the following vulnerability has been resolved:&lt;/p&gt;
&lt;p&gt;mm/rmap: fix incorrect pte restoration for lazyfree folios&lt;/p&gt;
&lt;p&gt;We batch unmap anonymous lazyfree folios by folio_unmap_pte_batch.  If the
batch has a mix of writable and non-writable bits, we may end up setting
the entire batch writable.  Fix this by respecting writable bit during
batching.&lt;/p&gt;
&lt;p&gt;Although on a successful unmap of a lazyfree folio, the soft-dirty bit is
lost, preserve it on pte restoration by respecting the bit during
batching, to make the fix consistent w.r.t both writable bit and
soft-dirty bit.&lt;/p&gt;
&lt;p&gt;I was able to write the below reproducer and crash the kernel. 
Explanation of reproducer (set 64K mTHP to always):&lt;/p&gt;
&lt;p&gt;Fault in a 64K large folio.  Split the VMA at mid-point with
MADV_DONTFORK.  fork() - parent points to the folio with 8 writable ptes
and 8 non-writable ptes.  Merge the VMAs with MADV_DOFORK so that
folio_unmap_pte_batch() can determine all the 16 ptes as a batch.  Do
MADV_FREE on the range to mark the folio as lazyfree.  Write to the memory
to dirty the pte, eventually rmap will dirty the folio.  Then trigger
reclaim, we will hit the pte restoration path, and the kernel will crash
with the trace given below.&lt;/p&gt;
&lt;p&gt;The BUG happens at:&lt;/p&gt;
&lt;p&gt;BUG_ON(atomic_inc_return(&amp;amp;ptc-&amp;gt;anon_map_count) &amp;gt; 1 &amp;amp;&amp;amp; rw);&lt;/p&gt;
&lt;p&gt;The code path is asking for anonymous page to be mapped writable into the
pagetable.  The BUG_ON() firing implies that such a writable page has been
mapped into the pagetables of more than one process,…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/cve-2026-31398</guid>
    </item>
  </channel>
</rss>
